a
    ߙfb$h                  .   @   s  d dl Z d dlZd dlmZ d dlmZmZm	Z	 d dl
mZmZ d dlmZ d dlmZ ddlmZ dd	lmZ dd
lmZ g dZejjZddddddZed ej d ej d ej d ej ej dej ej d ej ej ddded< ed ej d ej d ej d ej ej dej ej d ej ej ddded< edej dej d ej de ejej  ded< dddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d2d6d7d8d9d9d9d9d9d9d9d9d9d9d9d9d9d9d:d;d<-Z g Z!G d=d> d>Z"G d?d@ d@eeZ#G dAdB dBeeZ$dS )C    N)units)SpectralCoordGalacticICRS)update_differentials_to_matchattach_zero_velocities)AstropyUserWarning)c   )BaseLowLevelWCS)HighLevelWCSMixin)SlicedLowLevelWCS)custom_ctype_to_ucd_mappingSlicedFITSWCSFITSWCSAPIMixinZgcrsZicrsZhcrsZlsrkZlsrd)ZGEOCENTZBARYCENTZ	HELIOCENTZLSRKZLSRDi$Z	cartesian)uvwUVWZrepresentation_typeZdifferential_typeZGALACTOCiZLOCALGRPg}p@g      H@gv$T?)lbdistanceZradial_velocityZCMBDIPOLz	pos.eq.raz
pos.eq.deczpos.galactic.lonzpos.galactic.latzpos.ecliptic.lonzpos.ecliptic.latzpos.bodyrc.lonzpos.bodyrc.latzcustom:pos.helioprojective.latzcustom:pos.helioprojective.lonzcustom:pos.helioprojective.zz&custom:pos.heliographic.stonyhurst.lonz&custom:pos.heliographic.stonyhurst.latz&custom:pos.heliographic.carrington.lonz&custom:pos.heliographic.carrington.latzcustom:pos.heliocentric.xzcustom:pos.heliocentric.yzcustom:pos.heliocentric.zzem.freqz	em.energyzem.wavenumberzem.wlzspect.dopplerVeloc.radiozspect.dopplerVeloc.optzsrc.redshiftzspect.dopplerVeloczcustom:spect.doplerVeloc.betazphys.polarization.stokestimezpos.distancez!custom:pos.distance.sunToObserver)-ZRAZDECZGLONZGLATZELONZELATZTLONZTLATZHPLTZHPLNZHPRZZHGLNZHGLTZCRLNZCRLTZSOLXZSOLYZSOLZZFREQZENERZWAVNZWAVEVRADVOPTZOPTZAWAVVELOBETAZSTOKESZTIMEZTAIZTTZTDTZETZIATZUT1ZUTCZGMTZGPSZTCGZTCBZTDBZLOCALZDISTZDSUNc                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   a  
    A context manager that makes it possible to temporarily add new CTYPE to
    UCD1+ mapping used by :attr:`FITSWCSAPIMixin.world_axis_physical_types`.

    Parameters
    ----------
    mapping : dict
        A dictionary mapping a CTYPE value to a UCD1+ value

    Examples
    --------

    Consider a WCS with the following CTYPE::

        >>> from astropy.wcs import WCS
        >>> wcs = WCS(naxis=1)
        >>> wcs.wcs.ctype = ['SPAM']

    By default, :attr:`FITSWCSAPIMixin.world_axis_physical_types` returns `None`,
    but this can be overridden::

        >>> wcs.world_axis_physical_types
        [None]
        >>> with custom_ctype_to_ucd_mapping({'SPAM': 'food.spam'}):
        ...     wcs.world_axis_physical_types
        ['food.spam']
    c                 C   s   t d| || _d S Nr   )CTYPE_TO_UCD1_CUSTOMinsertmapping)selfr#    r%   9lib/python3.9/site-packages/astropy/wcs/wcsapi/fitswcs.py__init__   s    z$custom_ctype_to_ucd_mapping.__init__c                 C   s   d S Nr%   r$   r%   r%   r&   	__enter__   s    z%custom_ctype_to_ucd_mapping.__enter__c                 C   s   t | j d S r(   )r!   remover#   )r$   typevaluetbr%   r%   r&   __exit__   s    z$custom_ctype_to_ucd_mapping.__exit__N)__name__
__module____qualname____doc__r'   r*   r/   r%   r%   r%   r&   r      s   r   c                   @   s   e Zd ZdS )r   N)r0   r1   r2   r%   r%   r%   r&   r      s   r   c                   @   s   e Zd ZdZedd Zedd Zedd Zejdd Zed	d
 Z	e	jdd
 Z	edd Z
e
jdd Z
edd Zedd Zedd Zedd Zdd Zdd Zedd Zedd Zedd  Zd!d" Zd#S )$r   z
    A mix-in class that is intended to be inherited by the
    :class:`~astropy.wcs.WCS` class and provides the low- and high-level WCS API
    c                 C   s   | j S r(   )naxisr)   r%   r%   r&   pixel_n_dim   s    zFITSWCSAPIMixin.pixel_n_dimc                 C   s   t | jjS r(   )lenwcsctyper)   r%   r%   r&   world_n_dim   s    zFITSWCSAPIMixin.world_n_dimc                 C   s"   | j d u rd S | j d d d S d S Npixel_shaper)   r%   r%   r&   array_shape   s    
zFITSWCSAPIMixin.array_shapec                 C   s$   |d u rd | _ n|d d d | _ d S r:   r<   r$   r-   r%   r%   r&   r>      s    c                 C   s    | j ddgkrd S t| j S d S r    )_naxistupler)   r%   r%   r&   r=      s    zFITSWCSAPIMixin.pixel_shapec                 C   sF   |d u rddg| _ n.t|| jkr8td| jt|t|| _ d S )Nr   z9The number of data axes, {}, does not equal the shape {}.)r@   r6   r4   
ValueErrorformatlistr?   r%   r%   r&   r=      s    
c                 C   s   | j S r(   )_pixel_boundsr)   r%   r%   r&   pixel_bounds   s    zFITSWCSAPIMixin.pixel_boundsc                 C   sB   |d u r|| _ n.t|| jkr4td| jt|t|| _ d S )NzJThe number of data axes, {}, does not equal the number of pixel bounds {}.)rE   r6   r4   rB   rC   rD   r?   r%   r%   r&   rF      s    
c                 C   sx   g }| j jD ]f}| dr*|d q|dd }tD ]}||v r<|||   qq<|t| d  q|S )N)zUT(zTT(r   -r   )	r7   r8   upper
startswithappendsplitr!   CTYPE_TO_UCD1get)r$   typesr8   Z
ctype_nameZcustom_mappingr%   r%   r&   world_axis_physical_types  s    z)FITSWCSAPIMixin.world_axis_physical_typesc              	   C   sx   g }| j jD ]f}|d u rd}nJt|tjr8|jdd}n0zt|jdd}W n tjyf   d}Y n0 || q|S )N ZvounitrC   )r7   cunit
isinstancer   ZUnitZ	to_stringZ
UnitsErrorrJ   )r$   r   unitr%   r%   r&   world_axis_units  s    
z FITSWCSAPIMixin.world_axis_unitsc                 C   s   t | jjS r(   )rD   r7   Zcnamer)   r%   r%   r&   world_axis_names"  s    z FITSWCSAPIMixin.world_axis_namesc                 C   s   | j rtj| j| jftdS | j dk}| jjd d dk}t	|d }|D ]>}|D ]4}||krX||  || O  < ||  || O  < qXqP|S )N)Zdtyper     
      )
Zhas_distortionnpZonesr9   r5   boolr7   Zget_pcZ
axis_typesZnonzero)r$   Zmatrix	celestialZcelestial_indicesZworld1Zworld2r%   r%   r&   axis_correlation_matrix&  s    z'FITSWCSAPIMixin.axis_correlation_matrixc                 G   s.   | j g |dR  }| jdkr&|d S t|S Nr   r
   )Zall_pix2worldr9   rA   )r$   Zpixel_arraysworldr%   r%   r&   pixel_to_world_valuesA  s    z%FITSWCSAPIMixin.pixel_to_world_valuesc                 G   s.   | j g |dR  }| jdkr&|d S t|S r^   )Zall_world2pixr5   rA   )r$   Zworld_arraysZpixelr%   r%   r&   world_to_pixel_valuesE  s    z%FITSWCSAPIMixin.world_to_pixel_valuesc                 C   s   |   d S r    _get_components_and_classesr)   r%   r%   r&   world_axis_object_componentsI  s    z,FITSWCSAPIMixin.world_axis_object_componentsc                 C   s   |   d S )Nr
   rb   r)   r%   r%   r&   world_axis_object_classesM  s    z)FITSWCSAPIMixin.world_axis_object_classesc                 C   s   dS )NFr%   r)   r%   r%   r&   serialized_classesQ  s    z"FITSWCSAPIMixin.serialized_classesc           !   	      s  j tjjtjjjjjjjjjjjj	jj
f	}tdd d urpj}|d |krj|d S d _ddlm} ddlm}m} ddlm} ddlm m d gj  }i }jr z|}	W n ty   d }	Y n>0 i |	d< tjd	< |d
f|d< d|jj	< d|jj
< jrjj}
jj|
 d d }| }i tjj d rjd n|jj d d d	tj!i} jj"dd|d}||j#|d}jjt$v rt$jj }|%|t&|t'rt(nt)|t$jj ddn,jjdkrt(|nt*djj djr|	d ur|jj+jj	 jjjj	  jj+jj
 jjjj
  |	dtj, dt(nd d urz%t-  W n$ t.y   t/0dt1 d Y n0 d urz%t-  W n$ t.y   t/0dt1 d Y n0 |dkrffdd}fd d!}tj2d
i |f|d"< d"d|f|jj< n|d#krfd$d%}fd&d'}tj2d
i |f|d"< d"d|f|jj< nЈjj|
 d	< jj3dkrB|d(krd)d*< jj3tj4 d+< nJ|d,krd-d*< jj3tj4 d+< n$|d.krBd/d*< jj5tj! d+< fd0d1}fd2d3}tj2d
i |f|d"< d"d|f|jj< d4j6v rj67d4dk}t8j D ]8}j6| d4kr|rd5| }nd4}d }jj| 9 }|d4krjj:rjj:9 }nd}d6|v rb|;d6}|d | ||d d7  }}t/0d8|  d9|  t< |d:kr~d;d<d=}d>}n>| |v r||  }n"| j=vrtd?jj|  jj>9 }|?d@r"t@tjj d d rt/0dAt< d }n|jj d d d	tj!i}nF|dBkr@|dddtj!dC}n(|dDkrPd }nt/0dE| dFt< d } tAjjBd tAjjBd d||d|d ur|  fdGdH}fdIdJ}  d
i |f||< |d| f||< qt8j D ]|}|| d u rjj| CdKd 9 }|dDkr*dL}||v r@|dM7 }q*tj2d
d	jj| if||< |ddNf||< q|||ff_||fS )ON_components_and_classes_cacher   r
   )wcs_to_celestial_frame)SkyCoordEarthLocation)FITS_DEPRECATED_SCALES)Time	TimeDeltaframerT   r%   r\   )r\   r   zspherical.lon.degree)r\   r
   zspherical.lat.degree      ZmjdZutc)rC   scalelocation)obstimeT)Zpreserve_observer_frameZTOPOCENTzSPECSYS=z not yet supportedrW   )rn   r   zIobserver cannot be converted to ICRS, so will not be set on SpectralCoordzGtarget cannot be converted to ICRS, so will not be set on SpectralCoordr   c                    s,   t | tr| S t| d jj tj dS )Nr
   )rT   observertarget)rS   r   r7   restwavr   m)Zredshiftrt   r$   ru   r%   r&   spectralcoord_from_redshift  s
    
zPFITSWCSAPIMixin._get_components_and_classes.<locals>.spectralcoord_from_redshiftc                    sN    d u r,t dt | tjjj d S |  tjjj d S d S )N]No observer defined on WCS, SpectralCoord will be converted without any velocity frame changeg      ?)	warningswarnr   to_valuer   rw   r7   rv   $with_observer_stationary_relative_tospectralcoordrt   r$   r%   r&   redshift_from_spectralcoord  s    zPFITSWCSAPIMixin._get_components_and_classes.<locals>.redshift_from_spectralcoordZspectralr   c                    s8   t | tr| S t| t tjtj djjtj  dS )Nrelativistic)rT   doppler_conventiondoppler_restrt   ru   )rS   r   C_SIr   rw   sr7   rv   )Zbetarx   r%   r&   spectralcoord_from_beta  s    

zLFITSWCSAPIMixin._get_components_and_classes.<locals>.spectralcoord_from_betac                    sb   t jjt j } d u r@tdt | t jt j	 |t
 S |  t jt j	 |t
 S d S Nrz   )r   Zdoppler_relativisticr7   rv   rw   r{   r|   r   r}   r   r   r~   )r   Zdoppler_equivr   r%   r&   beta_from_spectralcoord  s    zLFITSWCSAPIMixin._get_components_and_classes.<locals>.beta_from_spectralcoordr   r   r   r   r   Zradior   Zopticalc                    s   t | fd S )N)rt   ru   )r   )r-   )kwargsrt   ru   r%   r&   spectralcoord_from_value(  s    zMFITSWCSAPIMixin._get_components_and_classes.<locals>.spectralcoord_from_valuec                    s>   d u r$t dt | jf i  S | jf i  S d S r   )r{   r|   r   r}   r~   r   )r   rt   r%   r&   value_from_spectralcoord+  s    zMFITSWCSAPIMixin._get_components_and_classes.<locals>.value_from_spectralcoordr   ztime.(r;   zDropping unsupported sub-scale z from scale Zgps   secrQ   ZtaizUnrecognized time CTYPE=ZtopocentzUMissing or incomplete observer location information, setting location in Time to NoneZ	geocenter)rT   rP   zObservation location 'z4' is not supported, setting location in Time to Nonec                    s   t |  r| S | dd S )Nr   rQ   )rS   )offset)rl   rm   reference_timer%   r&   time_from_reference_and_offset  s    
zSFITSWCSAPIMixin._get_components_and_classes.<locals>.time_from_reference_and_offsetc                    s
   |   j S r(   )r   )r   )r   r%   r&   offset_from_time_and_reference  s    zSFITSWCSAPIMixin._get_components_and_classes.<locals>.offset_from_time_and_referencerG   r_   _r-   )Dr4   rD   r7   r8   rR   ZradesysZspecsysZequinoxZdateobsZlngZlatgetattrrg   Zastropy.wcs.utilsrh   astropy.coordinatesri   rj   Zastropy.time.formatsrk   Zastropy.timerl   rm   Zhas_celestialrB   r   degZhas_spectralspecrH   rZ   ZisnanZobsgeorw   ZmjdobsZget_itrsVELOCITY_FRAMESZtransform_torS   strr   r   NotImplementedErrorZcrvalZkpcr   	Exceptionr{   r|   r   ZQuantityZrestfrqZHzrv   rO   countrangelowerZtimesysindexUserWarningZSCALEStrefposrI   anyZ
nan_to_numZmjdrefrK   )!r$   Zwcs_hashcacherh   ri   rj   rk   Z
componentsclassesZcelestial_frameZispecr8   Zearth_locationrs   Zobserver_locationrn   ry   r   r   r   r   r   Zmultiple_timeinameZreference_time_deltarq   posZsubscaler   rr   r   r   r%   )rl   rm   r   rt   r   r$   ru   r&   rc   U  sZ   








 







	













z+FITSWCSAPIMixin._get_components_and_classesN)r0   r1   r2   r3   propertyr5   r9   r>   setterr=   rF   rO   rU   rV   r]   r`   ra   rd   re   rf   rc   r%   r%   r%   r&   r      sD   
















r   )%r{   ZnumpyrZ   Zastropyr   r   r   r   r   r   Z'astropy.coordinates.spectral_coordinater   r   Zastropy.utils.exceptionsr   Zastropy.constantsr	   Zlow_level_apir   Zhigh_level_apir   Zwrappersr   __all__Zsir-   r   r   Zkmr   r   torL   r!   r   r   r   r%   r%   r%   r&   <module>   s   *
*

	=(