ó
šßÈ[c           @` sÏ   d  Z  d d l m Z m Z m Z m Z d d l Z d d l m	 Z	 d d l
 m Z d d l m Z d d	 l m Z d
 d d d g Z d d d „ Z d d d „ Z d d „ Z d d „ Z d d d „ Z d S(   uB   
This module contains functions for matching coordinate catalogs.
i    (   t   absolute_importt   divisiont   print_functiont   unicode_literalsNi   (   t   sixi   (   t   UnitSphericalRepresentation(   t   units(   t   Angleu   match_coordinates_3du   match_coordinates_skyu   search_around_3du   search_around_skyu	   kdtree_3dc         C` s+  | j  s t | ƒ d k  r* t d ƒ ‚ n  t | | ƒ } |  j | ƒ }  | j j j } |  j j j	 | ƒ } | j
 d t j | j ƒ d f ƒ } | j | j | ƒ \ } }	 | d k rç | d d … d f } |	 d d … d f }	 n  | |	 j |  ƒ }
 |	 j
 | j d ƒ |
 | j
 | j d ƒ | f S(   u8  
    Finds the nearest 3-dimensional matches of a coordinate or coordinates in
    a set of catalog coordinates.

    This finds the 3-dimensional closest neighbor, which is only different
    from the on-sky distance if ``distance`` is set in either ``matchcoord``
    or ``catalogcoord``.

    Parameters
    ----------
    matchcoord : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
        The coordinate(s) to match to the catalog.
    catalogcoord : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
        The base catalog in which to search for matches. Typically this will
        be a coordinate object that is an array (i.e.,
        ``catalogcoord.isscalar == False``)
    nthneighbor : int, optional
        Which closest neighbor to search for.  Typically ``1`` is desired here,
        as that is correct for matching one set of coordinates to another.
        The next likely use case is ``2``, for matching a coordinate catalog
        against *itself* (``1`` is inappropriate because each point will find
        itself as the closest match).
    storekdtree : bool or str, optional
        If a string, will store the KD-Tree used for the computation
        in the ``catalogcoord``, as in ``catalogcoord.cache`` with the
        provided name.  This dramatically speeds up subsequent calls with the
        same catalog. If False, the KD-Tree is discarded after use.

    Returns
    -------
    idx : integer array
        Indices into ``catalogcoord`` to get the matched points for each
        ``matchcoord``. Shape matches ``matchcoord``.
    sep2d : `~astropy.coordinates.Angle`
        The on-sky separation between the closest match for each ``matchcoord``
        and the ``matchcoord``. Shape matches ``matchcoord``.
    dist3d : `~astropy.units.Quantity`
        The 3D distance between the closest match for each ``matchcoord`` and
        the ``matchcoord``. Shape matches ``matchcoord``.

    Notes
    -----
    This function requires `SciPy <https://www.scipy.org/>`_ to be installed
    or it will fail.
    i   uC   The catalog for coordinate matching cannot be a scalar or length-0.i   Niÿÿÿÿ(   t   isscalart   lent
   ValueErrort   _get_cartesian_kdtreet   transform_tot	   cartesiant   xt   unitt   xyzt   tot   reshapet   npt   prodt   shapet   queryt   Tt
   separation(   t
   matchcoordt   catalogcoordt   nthneighbort   storekdtreet   kdtt   catunitt   matchxyzt   matchflatxyzt   distt   idxt   sep2d(    (    s;   lib/python2.7/site-packages/astropy/coordinates/matching.pyt   match_coordinates_3d   s    .%u
   kdtree_skyc         C` sA  | j  s t | ƒ d k  r* t d ƒ ‚ n  |  j | ƒ } | j j t ƒ } | j | ƒ } | j j t ƒ } | j | ƒ } | j j	 | | ƒ } t
 | | | | ƒ \ }	 }
 } t | j t ƒ pÏ t | j t ƒ sè | |	 j | ƒ } n  t | t j ƒ r| j | | j | <n# | t k r4| j d | j d <n  |	 |
 | f S(   uÈ  
    Finds the nearest on-sky matches of a coordinate or coordinates in
    a set of catalog coordinates.

    This finds the on-sky closest neighbor, which is only different from the
    3-dimensional match if ``distance`` is set in either ``matchcoord``
    or ``catalogcoord``.

    Parameters
    ----------
    matchcoord : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
        The coordinate(s) to match to the catalog.
    catalogcoord : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
        The base catalog in which to search for matches. Typically this will
        be a coordinate object that is an array (i.e.,
        ``catalogcoord.isscalar == False``)
    nthneighbor : int, optional
        Which closest neighbor to search for.  Typically ``1`` is desired here,
        as that is correct for matching one set of coordinates to another.
        The next likely use case is ``2``, for matching a coordinate catalog
        against *itself* (``1`` is inappropriate because each point will find
        itself as the closest match).
    storekdtree : bool or str, optional
        If a string, will store the KD-Tree used for the computation
        in the ``catalogcoord`` in ``catalogcoord.cache`` with the
        provided name.  This dramatically speeds up subsequent calls with the
        same catalog. If False, the KD-Tree is discarded after use.

    Returns
    -------
    idx : integer array
        Indices into ``catalogcoord`` to get the matched points for each
        ``matchcoord``. Shape matches ``matchcoord``.
    sep2d : `~astropy.coordinates.Angle`
        The on-sky separation between the closest match for each
        ``matchcoord`` and the ``matchcoord``. Shape matches ``matchcoord``.
    dist3d : `~astropy.units.Quantity`
        The 3D distance between the closest match for each ``matchcoord`` and
        the ``matchcoord``. Shape matches ``matchcoord``.  If either
        ``matchcoord`` or ``catalogcoord`` don't have a distance, this is the 3D
        distance on the unit sphere, rather than a true distance.

    Notes
    -----
    This function requires `SciPy <https://www.scipy.org/>`_ to be installed
    or it will fail.
    i   uC   The catalog for coordinate matching cannot be a scalar or length-0.u   kdtree(   R   R	   R
   R   t   datat   represent_asR   t   realize_framet   cachet   getR$   t
   isinstancet   separation_3dR   t   string_typest   True(   R   R   R   R   t   newmatcht   match_ureprt
   newmatch_ut	   cat_ureprt   newcat_uR"   R#   t   sep3d(    (    s;   lib/python2.7/site-packages/astropy/coordinates/matching.pyt   match_coordinates_skyZ   s"    0c         C` s
  | j  s t d ƒ ‚ n  |  j  s* | j  r9 t d ƒ ‚ n  t |  ƒ d k s] t | ƒ d k r¯ t j g  d t j ƒt j g  d t j ƒt g  t j ƒ t j	 g  |  j
 j ƒ f St | | ƒ } | j j j } |  j | ƒ }  t |  | d | ƒ} | j | ƒ } g  } g  }	 xQ t | j | | ƒ ƒ D]7 \ }
 } x( | D]  } | j |
 ƒ |	 j | ƒ q8Wq%Wt j | d t j ƒ} t j |	 d t j ƒ}	 | j d k rÌt g  t j ƒ } t j	 g  |  j
 j ƒ } n. |  | j | |	 ƒ } |  | j | |	 ƒ } | |	 | | f S(   uù	  
    Searches for pairs of points that are at least as close as a specified
    distance in 3D space.

    This is intended for use on coordinate objects with arrays of coordinates,
    not scalars.  For scalar coordinates, it is better to use the
    ``separation_3d`` methods.

    Parameters
    ----------
    coords1 : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
        The first set of coordinates, which will be searched for matches from
        ``coords2`` within ``seplimit``.  Cannot be a scalar coordinate.
    coords2 : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
        The second set of coordinates, which will be searched for matches from
        ``coords1`` within ``seplimit``.  Cannot be a scalar coordinate.
    distlimit : `~astropy.units.Quantity` with distance units
        The physical radius to search within.
    storekdtree : bool or str, optional
        If a string, will store the KD-Tree used in the search with the name
        ``storekdtree`` in ``coords2.cache``. This speeds up subsequent calls
        to this function. If False, the KD-Trees are not saved.

    Returns
    -------
    idx1 : integer array
        Indices into ``coords1`` that matches to the corresponding element of
        ``idx2``. Shape matches ``idx2``.
    idx2 : integer array
        Indices into ``coords2`` that matches to the corresponding element of
        ``idx1``. Shape matches ``idx1``.
    sep2d : `~astropy.coordinates.Angle`
        The on-sky separation between the coordinates. Shape matches ``idx1``
        and ``idx2``.
    dist3d : `~astropy.units.Quantity`
        The 3D distance between the coordinates. Shape matches ``idx1`` and
        ``idx2``. The unit is that of ``coords1``.

    Notes
    -----
    This function requires `SciPy <https://www.scipy.org/>`_ (>=0.12.0)
    to be installed or it will fail.

    If you are using this function to search in a catalog for matches around
    specific points, the convention is for ``coords2`` to be the catalog, and
    ``coords1`` are the points to search around.  While these operations are
    mathematically the same if ``coords1`` and ``coords2`` are flipped, some of
    the optimizations may work better if this convention is obeyed.

    In the current implementation, the return values are always sorted in the
    same order as the ``coords1`` (so ``idx1`` is in ascending order).  This is
    considered an implementation detail, though, so it could change in a future
    release.
    u.   distlimit must be a scalar in search_around_3dué   One of the inputs to search_around_3d is a scalar. search_around_3d is intended for use with array coordinates, not scalars.  Instead, use ``coord1.separation_3d(coord2) < distlimit`` to find the coordinates near a scalar coordinate.i    t   dtypet	   forceunit(   R   R
   R	   R   t   arrayt   intR   t   ut   degt   Quantityt   distanceR   R   R   R   R   t   to_valuet	   enumeratet   query_ball_treet   appendt   sizeR   R+   (   t   coords1t   coords2t	   distlimitR   t   kdt2t   cunitt   kdt1t   dt   idxs1t   idxs2t   it   matchest   matcht   d2dst   d3ds(    (    s;   lib/python2.7/site-packages/astropy/coordinates/matching.pyt   search_around_3d®   s6    7	$*%c         C` s  | j  s t d ƒ ‚ n  |  j  s* | j  r9 t d ƒ ‚ n  t |  ƒ d k s] t | ƒ d k rÖ | j j t j k r~ t j } n |  j j } t j g  d t j	 ƒt j g  d t j	 ƒt
 g  t j ƒ t j g  | ƒ f S|  j | ƒ }  |  j j t ƒ } |  j | ƒ } t | | ƒ } | r=| j j | ƒ r=| j | } nX | j j t ƒ }	 | j |	 ƒ }
 t |
 | ƒ } | r•| | j | t k rŽd n | <n  d t j t
 | ƒ d ƒ j } g  } g  } xQ t | j | | ƒ ƒ D]7 \ } } x( | D]  } | j | ƒ | j | ƒ qíWqÚWt j | d t j	 ƒ} t j | d t j	 ƒ} | j d k r¨| j j t j k rut j } n |  j j } t
 g  t j ƒ } t j g  | ƒ } n] |  | j | | ƒ } y |  | j | | ƒ } Wn( t k
 rd t j | d ƒ } n X| | | | f S(   u	  
    Searches for pairs of points that have an angular separation at least as
    close as a specified angle.

    This is intended for use on coordinate objects with arrays of coordinates,
    not scalars.  For scalar coordinates, it is better to use the ``separation``
    methods.

    Parameters
    ----------
    coords1 : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
        The first set of coordinates, which will be searched for matches from
        ``coords2`` within ``seplimit``. Cannot be a scalar coordinate.
    coords2 : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
        The second set of coordinates, which will be searched for matches from
        ``coords1`` within ``seplimit``. Cannot be a scalar coordinate.
    seplimit : `~astropy.units.Quantity` with angle units
        The on-sky separation to search within.
    storekdtree : bool or str, optional
        If a string, will store the KD-Tree used in the search with the name
        ``storekdtree`` in ``coords2.cache``. This speeds up subsequent calls
        to this function. If False, the KD-Trees are not saved.

    Returns
    -------
    idx1 : integer array
        Indices into ``coords1`` that matches to the corresponding element of
        ``idx2``. Shape matches ``idx2``.
    idx2 : integer array
        Indices into ``coords2`` that matches to the corresponding element of
        ``idx1``. Shape matches ``idx1``.
    sep2d : `~astropy.coordinates.Angle`
        The on-sky separation between the coordinates. Shape matches ``idx1``
        and ``idx2``.
    dist3d : `~astropy.units.Quantity`
        The 3D distance between the coordinates. Shape matches ``idx1``
        and ``idx2``; the unit is that of ``coords1``.
        If either ``coords1`` or ``coords2`` don't have a distance,
        this is the 3D distance on the unit sphere, rather than a
        physical distance.

    Notes
    -----
    This function requires `SciPy <https://www.scipy.org/>`_ (>=0.12.0)
    to be installed or it will fail.

    In the current implementation, the return values are always sorted in the
    same order as the ``coords1`` (so ``idx1`` is in ascending order).  This is
    considered an implementation detail, though, so it could change in a future
    release.
    u.   seplimit must be a scalar in search_around_skyuç   One of the inputs to search_around_sky is a scalar. search_around_sky is intended for use with array coordinates, not scalars.  Instead, use ``coord1.separation(coord2) < seplimit`` to find the coordinates near a scalar coordinate.i    R5   u   kdtreei   g       @(   R   R
   R	   R<   R   R9   t   dimensionless_unscaledR   R7   R8   R   R:   R;   R   R%   R&   R   R'   R   R(   R)   R-   t   sint   valueR>   R?   R@   RA   R   R+   (   RB   RC   t   seplimitR   t   distunitt   urepr1t   ucoords1RG   RE   t   urepr2t   ucoords2t   rRI   RJ   RK   RL   RM   RN   RO   (    (    s;   lib/python2.7/site-packages/astropy/coordinates/matching.pyt   search_around_sky  sV    4	$*" %u   kdtreec   	      C` sš  d d l  m } d d l m } y | j } Wn$ t k
 rS | d ƒ | j } n X| t k ri d } n  t | t	 j
 ƒ rÇ |  j j | d	 ƒ } | d	 k	 r
t | | ƒ r
t d j | ƒ ƒ ‚ q
nC t | | ƒ rå | } d	 } n% | sô d	 } n t d t | ƒ ƒ ‚ | d	 k r€| d	 k r1|  j j } n |  j j j | ƒ } | j d t j | j ƒ d f ƒ } | | j j ƒ } n  | r–| |  j | <n  | S(
   uÀ  
    This is a utility function to retrieve (and build/cache, if necessary)
    a 3D cartesian KD-Tree from various sorts of astropy coordinate objects.

    Parameters
    ----------
    coord : `~astropy.coordinates.BaseCoordinateFrame` or `~astropy.coordinates.SkyCoord`
        The coordinates to build the KD-Tree for.
    attrname_or_kdt : bool or str or KDTree
        If a string, will store the KD-Tree used for the computation in the
        ``coord``, in ``coord.cache`` with the provided name. If given as a
        KD-Tree, it will just be used directly.
    forceunit : unit or None
        If a unit, the cartesian coordinates will convert to that unit before
        being put in the KD-Tree.  If None, whatever unit it's already in
        will be used

    Returns
    -------
    kdt : `~scipy.spatial.cKDTree` or `~scipy.spatial.KDTree`
        The KD-Tree representing the 3D cartesian representation of the input
        coordinates.
    i    (   t   warn(   t   spatialuN   C-based KD tree not found, falling back on (much slower) python implementationu   kdtreeu3   The `attrname_or_kdt` "{0}" is not a scipy KD tree!u/   Invalid `attrname_or_kdt` argument for KD-Tree:i   N(   t   warningsR\   t   scipyR]   t   cKDTreet	   Exceptiont   KDTreeR-   R*   R   R,   R(   R)   t   Nonet	   TypeErrort   formatt   strR   R   R   R   R   R   R   RS   R   (	   t   coordt   attrname_or_kdtR6   R\   R]   Rb   R   t   cartxyzt   flatxyz(    (    s;   lib/python2.7/site-packages/astropy/coordinates/matching.pyR   ”  s:    
			%(   t   __doc__t
   __future__R    R   R   R   t   numpyR   t   externR   t   representationR   t    R   R9   R   t   __all__R$   R4   RP   R[   Rc   R   (    (    (    s;   lib/python2.7/site-packages/astropy/coordinates/matching.pyt   <module>   s   "		FTg