예제 #1
0
파일: core.py 프로젝트: kakirastern/regions
    def _convert_sky_coords(self):
        """
        Convert to sky coordinates
        """
        parsed_angles = [(x, y)
                         for x, y in zip(self.coord[:-1:2], self.coord[1::2])
                         if (isinstance(x, coordinates.Angle)
                             and isinstance(y, coordinates.Angle))]
        frame = coordinates.frame_transform_graph.lookup_name(self.coordsys)

        lon, lat = zip(*parsed_angles)
        if hasattr(lon, '__len__') and hasattr(
                lat, '__len__') and len(lon) == 1 and len(lat) == 1:
            # force entries to be scalar if they are length-1
            lon, lat = u.Quantity(lon[0]), u.Quantity(lat[0])
        else:
            # otherwise, they are vector quantities
            lon, lat = u.Quantity(lon), u.Quantity(lat)
        sphcoords = coordinates.UnitSphericalRepresentation(lon, lat)
        coords = [SkyCoord(frame(sphcoords))]

        if self.region_type != 'polygon':
            coords += self.coord[len(coords * 2):]

        return coords
예제 #2
0
    def __call__(
        self, n, *, frame=None, representation_type=None, random=None, **kwargs
    ):
        # Get preferred frames
        frame = self._infer_frame(frame)
        representation_type = self._infer_representation(representation_type)

        if random is None:
            random = np.random
        elif isinstance(random, int):
            random = np.random.default_rng(random)

        # return
        rep = coord.UnitSphericalRepresentation(
            lon=random.uniform(size=n) * u.deg,
            lat=2 * random.uniform(size=n) * u.deg,
        )

        if representation_type is None:
            representation_type = rep.__class__

        sample = coord.SkyCoord(
            frame.realize_frame(rep, representation_type=representation_type),
            copy=False,
        )
        sample.cache["mass"] = np.ones(n)
        sample.cache["potential"] = object()

        return sample
예제 #3
0
def sinehgc_to_hgc(sinehgc_coord, hgc_frame):
    lat = sinehgc_coord.lat
    lon = sinehgc_coord.lon

    lat_out = u.Quantity(np.sin(lat.value), u.deg)

    return hgc_frame.realize_frame(
        coord.UnitSphericalRepresentation(lat=lat_out, lon=lon))
예제 #4
0
def hgc_to_sinehgc(hgc_coord, sinehgc_frame):
    lat = hgc_coord.lat
    lon = hgc_coord.lon

    lat_out = u.Quantity(np.arcsin(lat.value), u.rad)

    return sinehgc_frame.realize_frame(
        coord.UnitSphericalRepresentation(lat=lat_out, lon=lon))
예제 #5
0
def test_pole_from_xyz():
    xnew = coord.UnitSphericalRepresentation(185*u.deg, 32.5*u.deg).to_cartesian()
    ynew = coord.UnitSphericalRepresentation(275*u.deg, 0*u.deg).to_cartesian()
    znew = xnew.cross(ynew)

    fr1 = GreatCircleICRSFrame.from_xyz(xnew, ynew, znew)
    fr2 = GreatCircleICRSFrame.from_xyz(xnew, ynew)
    fr3 = GreatCircleICRSFrame.from_xyz(xnew, znew=znew)
    fr4 = GreatCircleICRSFrame.from_xyz(ynew=ynew, znew=znew)

    for fr in [fr2, fr3, fr4]:
        assert np.isclose(fr1.pole.ra.degree, fr.pole.ra.degree)
        assert np.isclose(fr1.pole.dec.degree, fr.pole.dec.degree)
        assert np.isclose(fr1.center.ra.degree, fr.center.ra.degree)
        assert np.isclose(fr1.center.dec.degree, fr.center.dec.degree)

    with pytest.raises(ValueError):
        GreatCircleICRSFrame.from_xyz(xnew)
예제 #6
0
def zyx_euler_from_endpoints(lon1, lat1, lon2, lat2):
    c1 = coord.SkyCoord(lon1 * u.deg, lat1 * u.deg)
    c2 = coord.SkyCoord(lon2 * u.deg, lat2 * u.deg)
    fr = gc.GreatCircleICRSFrame.from_endpoints(c1, c2)
    origin = fr.realize_frame(
        coord.UnitSphericalRepresentation(0 * u.deg, 0 * u.deg))

    gc_icrs = origin.transform_to(coord.ICRS)
    R = gc.greatcircle.reference_to_greatcircle(coord.ICRS, fr)
    psi = -np.degrees(np.arctan2(R[2, 1], R[2, 2]))

    return [gc_icrs.ra.degree, gc_icrs.dec.degree, psi]
예제 #7
0
def get_rot(frame, x0=0.):

    trans = coord.frame_transform_graph.get_transform(coord.ICRS,
                                                      frame.__class__)
    for t in trans.transforms:
        if not isinstance(t, coord.transformations.StaticMatrixTransform):
            R = None
            break

    else:
        # All are static matrix transformations
        R = np.eye(3)
        for t in trans.transforms:
            R = R @ t.matrix

    origin = frame.realize_frame(
        coord.UnitSphericalRepresentation(0 * u.deg, 0 * u.deg))
    gc_icrs = origin.transform_to(coord.ICRS)

    if R is None:  # no simple matrix transformation:
        usph_band = coord.UnitSphericalRepresentation(
            np.random.uniform(0, 360, 10000) * u.deg,
            np.random.uniform(-1, 1, size=10000) * u.deg)
        band_icrs = frame.realize_frame(usph_band).transform_to(coord.ICRS)

        R1 = coord.matrix_utilities.rotation_matrix(gc_icrs.ra, 'z')
        R2 = coord.matrix_utilities.rotation_matrix(-gc_icrs.dec, 'y')
        Rtmp = R2 @ R1

        psi = get_roll(band_icrs, Rtmp, x0).degree

    else:
        origin = frame.realize_frame(
            coord.UnitSphericalRepresentation(0 * u.deg, 0 * u.deg))
        gc_icrs = origin.transform_to(coord.ICRS)
        psi = -np.degrees(np.arctan2(R[2, 1], R[2, 2]))

    return [gc_icrs.ra.degree, gc_icrs.dec.degree, psi]
예제 #8
0
def get_rot(fr, x0=0.):
    origin = get_origin(fr)
    usph_band = coord.UnitSphericalRepresentation(
        np.random.uniform(0, 360, 10000) * u.deg,
        np.random.uniform(-1, 1, size=10000) * u.deg)
    band_icrs = fr.realize_frame(usph_band).transform_to(coord.ICRS)

    R1 = rotation_matrix(origin.ra, 'z')
    R2 = rotation_matrix(-origin.dec, 'y')
    Rtmp = R2 @ R1

    roll = get_roll(band_icrs, Rtmp, x0)

    return [origin.ra.degree, origin.dec.degree, roll.degree]
예제 #9
0
def test_representation_representation():
    """
    Test that Representations are represented correctly.
    """
    # With no unit we get "None" in the unit row
    c = coordinates.CartesianRepresentation([0], [1], [0], unit=u.one)
    t = Table([c])
    assert t.pformat() == ['    col0    ',
                           '------------',
                           '(0., 1., 0.)']

    c = coordinates.CartesianRepresentation([0], [1], [0], unit='m')
    t = Table([c])
    assert t.pformat() == ['    col0    ',
                           '     m      ',
                           '------------',
                           '(0., 1., 0.)']

    c = coordinates.SphericalRepresentation([10]*u.deg, [20]*u.deg, [1]*u.pc)
    t = Table([c])
    assert t.pformat() == ['     col0     ',
                           ' deg, deg, pc ',
                           '--------------',
                           '(10., 20., 1.)']

    c = coordinates.UnitSphericalRepresentation([10]*u.deg, [20]*u.deg)
    t = Table([c])
    assert t.pformat() == ['   col0   ',
                           '   deg    ',
                           '----------',
                           '(10., 20.)']

    c = coordinates.SphericalCosLatDifferential(
        [10]*u.mas/u.yr, [2]*u.mas/u.yr, [10]*u.km/u.s)
    t = Table([c])
    assert t.pformat() == ['           col0           ',
                           'mas / yr, mas / yr, km / s',
                           '--------------------------',
                           '            (10., 2., 10.)']
예제 #10
0
def compute_stream_rotation_matrix(coords, zero_pt='mean'):
    """
    Compute the rotation matrix to go from the frame of the input
    coordinate to closely align the equator with the stream.

    .. note::

        if using zero_pt='mean' or 'median, the coordinates in the new system
        might not hit (0,0) because the mean / median is taken across each
        dimension separately.

    Parameters
    ----------
    coords : :class:`astropy.coordinate.SkyCoord`, :class:`astropy.coordinate.BaseCoordinateFrame`
        The coordinates of the stream stars.
    zero_pt : str,:class:`astropy.coordinate.SkyCoord`, :class:`astropy.coordinate.BaseCoordinateFrame`
        The origin of the new coordinates in the old coordinates.

    Returns
    -------
    R : :class:`~numpy.ndarray`
        A 3 by 3 rotation matrix (has shape ``(3,3)``) to convert heliocentric,
        Cartesian coordinates in the input coordinate frame to stream coordinates.

    """
    if hasattr(coords, 'spherical'):
        sph = coords.spherical
    else:
        sph = coords

    if zero_pt == 'mean' or zero_pt == 'median':
        lon = sph.lon.wrap_at(360 * u.degree)
        lat = sph.lat.wrap_at(90 * u.degree)

        if np.any(lon < 10 * u.degree) and np.any(
                lon > 350 * u.degree):  # it's wrapping
            lon = lon.wrap_at(180 * u.degree)

        if np.any(lat < -80 * u.degree) and np.any(
                lat > 80 * u.degree):  # it's wrapping
            lat = lat.wrap_at(180 * u.degree)

        zero_pt = coord.UnitSphericalRepresentation(lon=getattr(np,
                                                                zero_pt)(lon),
                                                    lat=getattr(np,
                                                                zero_pt)(lat))

    elif hasattr(zero_pt, 'spherical'):
        zero_pt = zero_pt.spherical

    # first determine rotation matrix to put zero_pt at (0,0)
    R1 = rotation_matrix(zero_pt.lon, 'z')
    R2 = rotation_matrix(-zero_pt.lat, 'y')

    xyz2 = (R2 * R1).dot(sph.represent_as(coord.CartesianRepresentation).xyz)

    # determine initial guess for angle with some math trickery
    _r = np.sqrt(xyz2[1]**2 + xyz2[2]**2)
    ix = _r.argmin()
    if ix == 0:
        ix += 1
    elif ix == (xyz2[1].size - 1):
        ix -= 1

    guess = 180 * u.degree - np.arctan2(xyz2[2][ix + 1] - xyz2[2][ix],
                                        xyz2[1][ix + 1] - xyz2[1][ix]).to(
                                            u.degree)
    res = minimize(_rotation_opt_func,
                   x0=np.cos(guess),
                   args=(xyz2, ),
                   method="powell")

    if not res.success:
        raise ValueError("Failed to compute final alignment angle.")

    if np.allclose(np.abs(res.x), 1., atol=1E-5):
        guess = 180 * u.degree - guess
        res = minimize(_rotation_opt_func,
                       x0=np.cos(guess),
                       args=(xyz2, ),
                       method="powell")

    R3 = rotation_matrix(np.arccos(res.x) * u.radian, 'x')
    R = R3 * R2 * R1

    return R
예제 #11
0
파일: read_ds9.py 프로젝트: mirca/regions
def line_parser(line, coordsys=None, errors='strict'):
    """
    Parse a single ds9 region line into a string

    Parameters
    ----------
    line : str
        A single ds9 region contained in a string
    coordsys : str
        The global coordinate system name declared at the top of the ds9 file
    errors : ``warn``, ``ignore``, ``strict``
      The error handling scheme to use for handling skipped entries
      in a region file that were not parseable.
      The default is 'strict', which will raise a ``DS9RegionParserError``.
      ``warn`` will raise a warning, and ``ignore`` will do nothing
      (i.e., be silent).

    Returns
    -------
    (region_type, parsed_return, parsed_meta, composite, include)
    region_type : str
    coord_list : list of coordinate objects
    meta : metadata dict
    composite : bool
        indicates whether region is a composite region
    include : bool
        Whether the region is included (False -> excluded)
    """
    if errors not in ('strict', 'ignore', 'warn'):
        raise ValueError("``errors`` must be one of strict, ignore, or warn")

    if '# Region file format' in line and line[0] == '#':
        # This is just a file format line, we can safely skip it
        return

    # special case / header: parse global parameters into metadata
    if line.lstrip()[:6] == 'global':
        return global_parser(line)

    region_type_search = region_type_or_coordsys_re.search(line)
    if region_type_search:
        include = region_type_search.groups()[0]
        region_type = region_type_search.groups()[1]
    else:
        # if there's no line, it's just blank, so don't warn
        if line:
            # but otherwise, this should probably always raise a warning?
            # at least until we identify common cases for it
            warn("No region type found for line '{0}'.".format(line),
                 DS9RegionParserWarning)
        return

    if region_type in coordinate_systems:
        return region_type  # outer loop has to do something with the coordinate system information
    elif region_type in language_spec:
        if coordsys is None:
            raise DS9RegionParserError("No coordinate system specified and a"
                                       " region has been found.")

        if "||" in line:
            composite = True
        else:
            composite = False

        # end_of_region_name is the coordinate of the end of the region's name, e.g.:
        # circle would be 6 because circle is 6 characters
        end_of_region_name = region_type_search.span()[1]
        # coordinate of the # symbol or end of the line (-1) if not found
        hash_or_end = line.find("#")
        coords_etc = strip_paren(
            line[end_of_region_name:hash_or_end].strip(" |"))
        meta_str = line[hash_or_end:]

        parsed_meta = meta_parser(meta_str)

        if coordsys in coordsys_name_mapping:
            parsed = type_parser(coords_etc, language_spec[region_type],
                                 coordsys_name_mapping[coordsys])

            # Reset iterator for ellipse annulus
            if region_type == 'ellipse':
                language_spec[region_type] = itertools.chain(
                    (coordinate, coordinate), itertools.cycle((radius, )))

            parsed_angles = [(x, y)
                             for x, y in zip(parsed[:-1:2], parsed[1::2])
                             if (isinstance(x, coordinates.Angle)
                                 and isinstance(y, coordinates.Angle))]
            frame = coordinates.frame_transform_graph.lookup_name(
                coordsys_name_mapping[coordsys])

            lon, lat = zip(*parsed_angles)
            if hasattr(lon, '__len__') and hasattr(
                    lon, '__lat__') and len(lon) == 1 and len(lat == 1):
                # force entries to be scalar if they are length-1
                lon, lat = u.Quantity(lon[0]), u.Quantity(lat[0])
            else:
                # otherwise, they are vector quantitites
                lon, lat = u.Quantity(lon), u.Quantity(lat)
            sphcoords = coordinates.UnitSphericalRepresentation(lon, lat)
            coords = frame(sphcoords)

            return region_type, [
                coords
            ] + parsed[len(coords) * 2:], parsed_meta, composite, include
        else:
            parsed = type_parser(coords_etc, language_spec[region_type],
                                 coordsys)
            if region_type == 'polygon':
                # have to special-case polygon in the phys coord case
                # b/c can't typecheck when iterating as in sky coord case
                coord = PixCoord(parsed[0::2], parsed[1::2])
                parsed_return = [coord]
            else:
                parsed = [_.value for _ in parsed]
                coord = PixCoord(parsed[0], parsed[1])
                parsed_return = [coord] + parsed[2:]

            # Reset iterator for ellipse annulus
            if region_type == 'ellipse':
                language_spec[region_type] = itertools.chain(
                    (coordinate, coordinate), itertools.cycle((radius, )))

            return region_type, parsed_return, parsed_meta, composite, include
    else:
        # This will raise warnings even if the first line is acceptable,
        # e.g. something like:
        # # Region file format: DS9 version 4.1
        # That behavior is unfortunate, but there's not a great workaround
        # except to let the user set `errors='ignore'`
        if errors in ('warn', 'strict'):
            message = (
                "Region type '{0}' was identified, but it is not one of "
                "the known region types.".format(region_type))
            if errors == 'strict':
                raise DS9RegionParserError(message)
            else:
                warn(message, DS9RegionParserWarning)
예제 #12
0
def fit_frame(
    data: coord.BaseCoordinateFrame,
    origin: coord.BaseCoordinateFrame,
    rot0: u.Quantity = 0 * u.deg,
    bounds: T.Sequence = (-np.inf, np.inf),
    *,
    fix_origin: bool = _minimize_defaults["fix_origin"],
    use_lmfit: T.Optional[bool] = _minimize_defaults["use_lmfit"],
    leastsquares: bool = _minimize_defaults["leastsquares"],
    align_v: bool = _minimize_defaults["align_v"],
    **fit_kwargs,
):
    """Find Best-Fit Rotated Frame.

    Parameters
    ----------
    data : :class:`~astropy.coordinates.CartesianRepresentation`
        If `align_v`, must have attached differentials

    rot0 : |Quantity|
        Initial guess for rotation
    origin : :class:`~astropy.coordinates.BaseCoordinateFrame`
        location of point on sky about which to rotate

    bounds : array-like, optional
        Parameter bounds.
        See :func:`~trackstream.preprocess.fit_rotated_frame.make_bounds`
        ::
            [[rot_low, rot_up],
             [lon_low, lon_up],
             [lat_low, lat_up]]

    Returns
    -------
    res : Any
        The result of the minimization. Depends on arguments.
    Dict[str, Any]
        Has fields "rotation" and "origin".

    Other Parameters
    ----------------
    use_lmfit : bool, optional, kwarg only
        Whether to use ``lmfit`` package
    leastsquares : bool, optional, kwarg only
        If `use_lmfit` is False, whether to to use
        :func:`~scipy.optimize.least_square` or
        :func:`~scipy.optimize.minimize` (default)

    align_v : bool, optional, kwarg only
        Whether to align velocity to be in positive direction

    fit_kwargs:
        Into whatever minimization package / function is used.

    Raises
    ------
    ValueError
        If `use_lmfit` and lmfit is not installed.

    """
    # ------------------------
    # Inputs

    # Data
    # need to make sure Cartesian representation
    # data = data.represent_as(
    #     coord.CartesianRepresentation,
    #     differential_class=coord.CartesianDifferential,
    # )

    # Origin
    # We work with a SphericalRepresentation, but
    # if isinstance(origin, coord.SkyCoord):
    #     raise TypeError
    origin_frame = origin.__class__
    origin = origin.represent_as(coord.SphericalRepresentation)

    if use_lmfit is None:
        use_lmfit = conf.use_lmfit

    x0 = u.Quantity([rot0, origin.lon, origin.lat]).to_value(u.deg)
    subsel = fit_kwargs.pop("subsel", Ellipsis)

    # ------------------------
    # Fitting

    if use_lmfit:  # lmfit
        if not HAS_LMFIT:
            raise ValueError("`lmfit` package not available.")

        res, values = _fit_representation_lmfit(
            data.cartesian,
            x0=x0,
            bounds=bounds,
            fix_origin=fix_origin,
            **fit_kwargs,
        )

    else:  # scipy
        res, values = _fit_representation_scipy(
            data.cartesian,
            x0=x0,
            bounds=bounds,
            fix_origin=fix_origin,
            use_leastsquares=leastsquares,
            **fit_kwargs,
        )

    # /def

    # ------------------------
    # Return

    best_rot = values[0]
    best_origin = coord.UnitSphericalRepresentation(
        lon=values[1],
        lat=values[2],  # TODO re-add distance
    )
    best_origin = origin_frame(best_origin)

    values = dict(rotation=best_rot, origin=best_origin)
    if align_v:
        values = align_v_positive_lon(data, values, subsel=subsel)

    return res, values
예제 #13
0
    def test__fix_branch_cuts(self):
        """Test method ``_fix_branch_cuts``.

        .. todo::

            graphical proof via mpl_test that the point hasn't moved.

        """
        # -------------------------------
        # no angular units

        rep = coord.CartesianRepresentation(
            x=[1, 2] * u.kpc,
            y=[3, 4] * u.kpc,
            z=[5, 6] * u.kpc,
        )
        array = rep._values.view(dtype=np.float64).reshape(rep.shape[0], -1).T
        got = self.inst._fix_branch_cuts(array, rep.__class__, rep._units)

        assert got is array

        # -------------------------------
        # UnitSphericalRepresentation

        # 1) all good
        rep = coord.UnitSphericalRepresentation(
            lon=[1, 2] * u.deg,
            lat=[3, 4] * u.deg,
        )
        array = rep._values.view(dtype=np.float64).reshape(rep.shape[0], -1).T
        got = self.inst._fix_branch_cuts(
            array.copy(),
            rep.__class__,
            rep._units,
        )
        assert np.allclose(got, array)

        # 2) needs correction
        array = np.array([[-360, 0, 360], [-91, 0, 91]])
        got = self.inst._fix_branch_cuts(
            array.copy(),
            rep.__class__,
            rep._units,
        )
        assert np.allclose(got, np.array([[-180, 0, 540], [-89, 0, 89]]))

        # -------------------------------
        # SphericalRepresentation

        # 1) all good
        rep = coord.SphericalRepresentation(
            lon=[1, 2] * u.deg,
            lat=[3, 4] * u.deg,
            distance=[5, 6] * u.kpc,
        )
        array = rep._values.view(dtype=np.float64).reshape(rep.shape[0], -1).T
        got = self.inst._fix_branch_cuts(
            array.copy(),
            rep.__class__,
            rep._units,
        )
        assert np.allclose(got, array)

        # 2) needs correction
        array = np.array([[-360, 0, 360], [-91, 0, 91], [5, 6, 7]])
        got = self.inst._fix_branch_cuts(
            array.copy(),
            rep.__class__,
            rep._units,
        )
        assert np.allclose(
            got,
            np.array([[-180, 0, 540], [-89, 0, 89], [5, 6, 7]]),
        )

        # 3) needs correction
        array = np.array([[-360, 0, 360], [-91, 0, 91], [-5, 6, -7]])
        got = self.inst._fix_branch_cuts(
            array.copy(),
            rep.__class__,
            rep._units,
        )
        assert np.allclose(
            got,
            np.array([[0, 0, 720], [89, 0, -89], [5, 6, 7]]),
        )

        # -------------------------------
        # CylindricalRepresentation

        # 1) all good
        rep = coord.CylindricalRepresentation(
            rho=[5, 6] * u.kpc,
            phi=[1, 2] * u.deg,
            z=[3, 4] * u.parsec,
        )
        array = rep._values.view(dtype=np.float64).reshape(rep.shape[0], -1).T
        got = self.inst._fix_branch_cuts(
            array.copy(),
            rep.__class__,
            rep._units,
        )
        assert np.allclose(got, array)

        # 2) needs correction
        array = np.array([[-5, 6, -7], [-180, 0, 180], [-4, 4, 4]])
        got = self.inst._fix_branch_cuts(
            array.copy(),
            rep.__class__,
            rep._units,
        )
        assert np.allclose(got, np.array([[5, 6, 7], [0, 0, 360], [-4, 4, 4]]))

        # -------------------------------
        # NotImplementedError

        with pytest.raises(NotImplementedError):

            rep = coord.PhysicsSphericalRepresentation(
                phi=[1, 2] * u.deg,
                theta=[3, 4] * u.deg,
                r=[5, 6] * u.kpc,
            )
            array = (rep._values.view(dtype=np.float64).reshape(
                rep.shape[0], -1).T)
            self.inst._fix_branch_cuts(
                array.copy(),
                coord.PhysicsSphericalRepresentation,
                rep._units,
            )
예제 #14
0
def line_parser(line, coordsys=None):
    """
    Parse a single ds9 region line into a string

    Parameters
    ----------
    line : str
        A single ds9 region contained in a string
    coordsys : str
        The global coordinate system name declared at the top of the ds9 file

    Returns
    -------
    (region_type, parsed_return, parsed_meta, composite, include)
    region_type : str
    coord_list : list of coordinate objects
    meta : metadata dict
    composite : bool
        indicates whether region is a composite region
    include : bool
        Whether the region is included (False -> excluded)
    """
    region_type_search = region_type_or_coordsys_re.search(line)
    if region_type_search:
        include = region_type_search.groups()[0]
        region_type = region_type_search.groups()[1]
    else:
        return

    if region_type in coordinate_systems:
        return region_type  # outer loop has to do something with the coordinate system information
    elif region_type in language_spec:
        if coordsys is None:
            raise ValueError(
                "No coordinate system specified and a region has been found.")

        if "||" in line:
            composite = True
        else:
            composite = False

        # end_of_region_name is the coordinate of the end of the region's name, e.g.:
        # circle would be 6 because circle is 6 characters
        end_of_region_name = region_type_search.span()[1]
        # coordinate of the # symbol or end of the line (-1) if not found
        hash_or_end = line.find("#")
        coords_etc = strip_paren(
            line[end_of_region_name:hash_or_end].strip(" |"))
        meta_str = line[hash_or_end:]

        parsed_meta = meta_parser(meta_str)

        if coordsys in coordsys_name_mapping:
            parsed = type_parser(coords_etc, language_spec[region_type],
                                 coordsys_name_mapping[coordsys])

            # Reset iterator for ellipse annulus
            if region_type == 'ellipse':
                language_spec[region_type] = itertools.chain(
                    (coordinate, coordinate), itertools.cycle((radius, )))

            parsed_angles = [(x, y)
                             for x, y in zip(parsed[:-1:2], parsed[1::2])
                             if isinstance(x, coordinates.Angle)
                             and isinstance(x, coordinates.Angle)]
            frame = coordinates.frame_transform_graph.lookup_name(
                coordsys_name_mapping[coordsys])

            lon, lat = zip(*parsed_angles)
            lon, lat = u.Quantity(lon), u.Quantity(lat)
            sphcoords = coordinates.UnitSphericalRepresentation(lon, lat)
            coords = frame(sphcoords)

            return region_type, [
                coords
            ] + parsed[len(coords) * 2:], parsed_meta, composite, include
        else:
            parsed = type_parser(coords_etc, language_spec[region_type],
                                 coordsys)
            if region_type == 'polygon':
                # have to special-case polygon in the phys coord case b/c can't typecheck when iterating as in sky coord case
                coord = PixCoord(parsed[0::2], parsed[1::2])
                parsed_return = [coord]
            else:
                parsed = [_.value for _ in parsed]
                coord = PixCoord(parsed[0], parsed[1])
                parsed_return = [coord] + parsed[2:]

            # Reset iterator for ellipse annulus
            if region_type == 'ellipse':
                language_spec[region_type] = itertools.chain(
                    (coordinate, coordinate), itertools.cycle((radius, )))

            return region_type, parsed_return, parsed_meta, composite, include
예제 #15
0
def test__make_bounds_defaults():
    """Test `~trackstream.preprocess.rotated_frame._make_bounds_defaults`."""
    expected = set(("rot_lower", "rot_upper", "origin_lim"))
    assert set(rotated_frame._make_bounds_defaults.keys()) == expected


# /def


# TODO use hypothesis instead
@pytest.mark.parametrize(
    "origin,rot_lower,rot_upper,origin_lim,expected",
    [
        (
            coord.UnitSphericalRepresentation(lon=0 * u.deg, lat=0 * u.deg),
            -1 * u.deg,
            2 * u.deg,
            3 * u.deg,
            np.c_[[-1, 2], [-3, 3], [-3, 3]].T,
        ),
        (
            coord.UnitSphericalRepresentation(lon=10 * u.deg, lat=11 * u.deg),
            -1 * u.deg,
            2 * u.deg,
            3 * u.deg,
            np.c_[[-1, 2], [7, 13], [8, 14]].T,
        ),
    ],
)
def test_make_bounds(
예제 #16
0
def get_origin(fr):
    usph_origin = coord.UnitSphericalRepresentation(0 * u.deg, 0 * u.deg)
    return fr.realize_frame(usph_origin).transform_to(coord.ICRS)