U
    e»{j¥`  ã                   @   sÈ   d Z ddlZddlZddlZddlZddlmZmZ ddl	m
Z
 ddlmZmZ ddd	gZG d
d	„ d	eƒZG dd„ deeƒZG dd„ deƒZdd„ Zddd„Zdd„ Zdd„ ZG dd„ dƒZdd„ ZdS )z¢
This module defines classes that deal with parameters.

It is unlikely users will need to work with these classes directly,
unless they define their own models.
é    N)ÚMagUnitÚQuantity)Ú
isiterableé   )Úarray_repr_onelineÚget_inputs_and_paramsÚ	ParameterÚInputParameterErrorÚParameterErrorc                   @   s   e Zd ZdZdS )r
   zDGeneric exception class for all exceptions pertaining to Parameters.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   úZ/var/www/html/bwave/python/venv/lib/python3.8/site-packages/astropy/modeling/parameters.pyr
      s   c                   @   s   e Zd ZdZdS )r	   z:Used for incorrect input parameter values and definitions.Nr   r   r   r   r   r	      s   c                   @   s   e Zd ZdZdS )ÚParameterDefinitionErrorz3Exception in declaration of class-level Parameters.Nr   r   r   r   r   r   "   s   r   c              	   C   sÂ   t | ƒrJztj| td�} W q¾ ttfk
rF   tdt| ƒ› d�ƒ‚Y q¾X ntt| t	ƒrVnht| tj
ƒrpt|  ¡ ƒ} nNt| tjtjfƒr–t| tƒs–t| ƒ} n(t| tƒrªtdƒ‚ntdt| ƒ› d�ƒ‚| S )z+Convert a parameter to float or float array©ÚdtypezParameter of z  could not be converted to floatz7Expected parameter to be of numerical type, not booleanz'Don't know how to convert parameter of z	 to float)r   ÚnpZ
asanyarrayÚfloatÚ	TypeErrorÚ
ValueErrorr	   ÚtypeÚ
isinstancer   ZndarrayÚitemÚnumbersÚNumberÚnumberÚbool)Úvaluer   r   r   Ú_tofloat&   s*    ÿ


ÿÿr!   Fc                    s   t  ˆ ¡‡ ‡fdd„ƒ}|S )Nc                    s<   | j d k	rt| j| j ƒ}n| j}ˆr.ˆ ||ƒS ˆ ||ƒS d S ©N©Úunitr   r    ©ÚselfÚvalÚ
self_value©ÚopÚ	reflectedr   r   ÚwrapperI   s    

z-_binary_arithmetic_operation.<locals>.wrapper©Ú	functoolsÚwraps)r*   r+   r,   r   r)   r   Ú_binary_arithmetic_operationH   s    r0   c                    s   t  ˆ ¡‡ fdd„ƒ}|S )Nc                    s*   | j d k	rt| j| j ƒ}n| j}ˆ ||ƒS r"   r#   r%   ©r*   r   r   r,   Y   s    
z-_binary_comparison_operation.<locals>.wrapperr-   ©r*   r,   r   r1   r   Ú_binary_comparison_operationX   s    r3   c                    s   t  ˆ ¡‡ fdd„ƒ}|S )Nc                    s(   | j d k	rt| j| j ƒ}n| j}ˆ |ƒS r"   r#   )r&   r(   r1   r   r   r,   f   s    
z,_unary_arithmetic_operation.<locals>.wrapperr-   r2   r   r1   r   Ú_unary_arithmetic_operatione   s    r4   c                       sô  e Zd ZdZdZdT‡ fdd„	Zdd	„ Zd
d„ Zdd„ Zdd„ Z	d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dUd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jd+d*„ ƒZed,d-„ ƒZejd.d-„ ƒZed/d0„ ƒZejd1d0„ ƒZed2d3„ ƒZejd4d3„ ƒZed5d6„ ƒZejd7d6„ ƒZed8d9„ ƒZejd:d9„ ƒZed;d<„ ƒZejd=d<„ ƒZed>d?„ ƒZejd@d?„ ƒZedAdB„ ƒZdCdD„ ZdVdEdF„Z edGdH„ ƒZ!e!jdIdH„ ƒZ!edJdK„ ƒZ"dLdM„ Z#dWdNdO„Z$dPdQ„ Z%e&e'j(ƒZ)e&e'j(dRdS�Z*e&e'j+ƒZ,e&e'j+dRdS�Z-e&e'j.ƒZ/e&e'j.dRdS�Z0e&e'j1ƒZ2e&e'j1dRdS�Z3e&e'j4ƒZ5e&e'j4dRdS�Z6e7e'j8ƒZ9e7e'j:ƒZ;e7e'j<ƒZ=e7e'j>ƒZ?e7e'j@ƒZAe7e'jBƒZCeDe'jEƒZFeDe'jGƒZH‡  ZIS )Xr   aw  
    Wraps individual parameters.

    Since 4.0 Parameters are no longer descriptors and are based on a new
    implementation of the Parameter class. Parameters now  (as of 4.0) store
    values locally (as instead previously in the associated model)

    This class represents a model's parameter (in a somewhat broad sense). It
    serves a number of purposes:

    1) A type to be recognized by models and treated specially at class
    initialization (i.e., if it is found that there is a class definition
    of a Parameter, the model initializer makes a copy at the instance level).

    2) Managing the handling of allowable parameter values and once defined,
    ensuring updates are consistent with the Parameter definition. This
    includes the optional use of units and quantities as well as transforming
    values to an internally consistent representation (e.g., from degrees to
    radians through the use of getters and setters).

    3) Holding attributes of parameters relevant to fitting, such as whether
    the parameter may be varied in fitting, or whether there are constraints
    that must be satisfied.



    See :ref:`astropy:modeling-parameters` for more details.

    Parameters
    ----------
    name : str
        parameter name

        .. warning::

            The fact that `Parameter` accepts ``name`` as an argument is an
            implementation detail, and should not be used directly.  When
            defining a new `Model` class, parameter names are always
            automatically defined by the class attribute they're assigned to.
    description : str
        parameter description
    default : float or array
        default value to use for this parameter
    unit : `~astropy.units.Unit`
        if specified, the parameter will be in these units, and when the
        parameter is updated in future, it should be set to a
        :class:`~astropy.units.Quantity` that has equivalent units.
    getter : callable
        a function that wraps the raw (internal) value of the parameter
        when returning the value through the parameter proxy (eg. a
        parameter may be stored internally as radians but returned to the
        user as degrees)
    setter : callable
        a function that wraps any values assigned to this parameter; should
        be the inverse of getter
    fixed : bool
        if True the parameter is not varied during fitting
    tied : callable or False
        if callable is supplied it provides a way to link the value of this
        parameter to another parameter (or some other arbitrary function)
    min : float
        the lower bound of a parameter
    max : float
        the upper bound of a parameter
    bounds : tuple
        specify min and max as a single tuple--bounds may not be specified
        simultaneously with min or max
    mag : bool
        Specify if the unit of the parameter can be a Magnitude unit or not
    )ÚfixedÚtiedÚboundsÚ NFc                    s*  t ƒ  ¡  d | _d| _|  |d ¡| _|  |d ¡| _|| _| ¡  | _	| _
t|tƒr†|d k	rz| |j¡sztd|› d|› �ƒ‚|j}|j}|| _|| _| j|dd� d | _| jsÆ| jd k	rÀ| j| _nd | _|d k	rî|	d k	sÞ|
d k	rötd|› �ƒ‚n|	|
f}|| _|| _|| _d | _d | _|| _|| _d | _d S )NFzparameter default z5 does not have units equivalent to the required unit T©ÚforcezXbounds may not be specified simultaneously with min or max when instantiating Parameter )ÚsuperÚ__init__Ú_modelÚ_model_requiredÚ_create_value_wrapperÚ_setterÚ_getterÚ_nameÚstripr   Z_descriptionr   r   Zis_equivalentr$   r   r    Ú_defaultÚ_magÚ	_set_unitÚ_internal_unitÚ_valuer   Ú_fixedÚ_tiedÚ_boundsÚ_orderÚ
_validatorÚ_priorÚ
_posteriorÚ_std)r&   ÚnameÚdescriptionÚdefaultr$   ÚgetterÚsetterr5   r6   ÚminÚmaxr7   ÚpriorÚ	posteriorÚmag©Ú	__class__r   r   r<   Ã   sH    

ÿ

ÿzParameter.__init__c                 C   s
   || _ d S r"   ©rB   )r&   ÚownerrQ   r   r   r   Ú__set_name__  s    zParameter.__set_name__c                 C   s"   | j }|jdkrdS |jd S d S )Nr   r   r   )r    Úshape©r&   r'   r   r   r   Ú__len__  s    
zParameter.__len__c                 C   s"   | j }t|jƒdkr|g}|| S )Nr   )r    Úlenr`   )r&   Úkeyr    r   r   r   Ú__getitem__  s    zParameter.__getitem__c                 C   sª   | j }t|tƒrbt|| ƒdkr2td| j› d�ƒ‚tt| t| ƒ¡Ž |ƒD ]\}}|  	||¡ qJnDz|||< W n6 t
k
r¤   td|› d| j›d|jd › �ƒ‚Y nX d S )Nr   z7Slice assignment outside the parameter dimensions for 'ú'zInput dimension z invalid for z parameter with dimension )r    r   Úslicerc   r	   rQ   ÚzipÚrangeÚindicesÚ__setitem__Ú
IndexErrorr`   )r&   rd   r    ZoldvalueÚidxr'   r   r   r   rk     s    
ÿ ÿzParameter.__setitem__c                 C   s~   d| j › d�}|d| j› �7 }| jd k	r8|d| j› �7 }| jD ]*}t| |ƒ}|dkr>|d|› d|› �7 }q>| jj› d|› d�S )	Nrf   z, value=z, unit=)NF)NNz, ú=ú(ú))rB   r    r$   ÚconstraintsÚgetattrr\   r   )r&   ÚargsZconsr'   r   r   r   Ú__repr__4  s    


zParameter.__repr__c                 C   s   | j S )zParameter namer]   ©r&   r   r   r   rQ   D  s    zParameter.namec                 C   s   | j S )zParameter default value)rD   ru   r   r   r   rS   J  s    zParameter.defaultc                 C   sp   | j dkr | jdkr t | j¡S | jrBt |   | j| j| j¡j¡S | j rZt |   | j¡¡S | jrlt | j¡S dS )z.The unadorned value proxied by this parameter.N)	rA   r@   r   Úfloat64rH   Úinternal_unitÚ_internal_valuer$   r    ru   r   r   r   r    O  s      ÿÿzParameter.valuec                 C   sL   t |tƒrtdƒ‚| jd kr0tj|tjd�| _ntj|  |¡tjd�| _d S )Nz°The .value property on parameters should be set to unitless values, not Quantity objects. To seta parameter to a quantity simply set the parameter directly without using .valuer   )	r   r   r   r@   r   Úarrayrv   rH   rx   ©r&   r    r   r   r   r    e  s    
ÿ
c                 C   s   | j S )zô
        The unit attached to this parameter, if any.

        On unbound parameters (i.e. parameters accessed through the
        model class, rather than a model instance) this is the required/
        default unit for the parameter.
        )Ú_unitru   r   r   r   r$   s  s    
zParameter.unitc                 C   s    | j d krtdƒ‚ntdƒ‚d S )NzNCannot attach units to parameters that were not initially specified with unitszYCannot change the unit attribute directly, instead change the parameter to a new quantity)r$   r   )r&   r$   r   r   r   r$     s    
ÿÿc                 C   s4   |r*t |tƒr"| js"td|› �ƒ‚|| _n|| _d S )Nz<This parameter does not support the magnitude units such as )r   r   rE   r   r{   r$   )r&   r$   r:   r   r   r   rF   Œ  s    ÿzParameter._set_unitc                 C   s   | j S )z[
        Return the internal unit the parameter uses for the internal value stored
        ©rG   ru   r   r   r   rw   —  s    zParameter.internal_unitc                 C   s
   || _ dS )z{
        Set the unit the parameter will convert the supplied value to the
        representation used internally.
        Nr|   )r&   rw   r   r   r   rw   ž  s    c                 C   s   | j dkrdS | j| j  S )zQ
        This parameter, as a :class:`~astropy.units.Quantity` instance.
        N)r$   r    ru   r   r   r   Úquantity¦  s    
zParameter.quantityc                 C   s.   t |tƒstdƒ‚|j| _| j|jdd� d S )Nz:The .quantity attribute should be set to a Quantity objectTr9   )r   r   r   r    rF   r$   )r&   r}   r   r   r   r}   ¯  s    
ÿc                 C   s   | j dkr| jjS | jjS )z*The shape of this parameter's value array.N)r@   rH   r`   rx   ru   r   r   r   r`   ¸  s    
zParameter.shapec                 C   s,   t | jtjƒr |dkr(tdƒ‚n|| j_d S )N)r   )r   z-Cannot assign this shape to a scalar quantity)r   r    r   Zgenericr   r`   rz   r   r   r   r`   ¿  s    
c                 C   s   t  | j¡S )z)The size of this parameter's value array.)r   Úsizer    ru   r   r   r   r~   Ç  s    zParameter.sizec                 C   s   | j S )z*Standard deviation, if available from fit.©rP   ru   r   r   r   ÚstdÍ  s    zParameter.stdc                 C   s
   || _ d S r"   r   rz   r   r   r   r€   Ó  s    c                 C   s   | j S r"   ©rN   ru   r   r   r   rX   ×  s    zParameter.priorc                 C   s
   || _ d S r"   r�   ra   r   r   r   rX   Û  s    c                 C   s   | j S r"   ©rO   ru   r   r   r   rY   ß  s    zParameter.posteriorc                 C   s
   || _ d S r"   r‚   ra   r   r   r   rY   ã  s    c                 C   s   | j S )zS
        Boolean indicating if the parameter is kept fixed during fitting.
        )rI   ru   r   r   r   r5   ç  s    zParameter.fixedc                 C   s   t |tƒstdƒ‚|| _dS )zFix a parameter.zValue must be booleanN)r   r   r   rI   rz   r   r   r   r5   î  s    
c                 C   s   | j S )z”
        Indicates that this parameter is linked to another one.

        A callable which provides the relationship of the two parameters.
        )rJ   ru   r   r   r   r6   õ  s    zParameter.tiedc                 C   s"   t |ƒs|dkrtdƒ‚|| _dS )zTie a parameter)FNz/Tied must be a callable or set to False or NoneN)Úcallabler   rJ   rz   r   r   r   r6   ÿ  s    c                 C   s   | j S )z8The minimum and maximum values of a parameter as a tuple)rK   ru   r   r   r   r7     s    zParameter.boundsc                 C   s’   |\}}|dk	rFt |tjtfƒs(tdƒ‚t |tƒr>t|jƒ}nt|ƒ}|dk	r„t |tjtfƒsftdƒ‚t |tƒr|t|jƒ}nt|ƒ}||f| _dS )z>Set the minimum and maximum values of a parameter from a tupleNz(Min value must be a number or a Quantityz(Max value must be a number or a Quantity)r   r   r   r   r   r   r    rK   )r&   r    Ú_minÚ_maxr   r   r   r7     s    

c                 C   s
   | j d S )z6A value used as a lower bound when fitting a parameterr   ©r7   ru   r   r   r   rV   $  s    zParameter.minc                 C   s   || j f| _dS )z"Set a minimum value of a parameterN)rW   r7   rz   r   r   r   rV   *  s    c                 C   s
   | j d S )z7A value used as an upper bound when fitting a parameterr   r†   ru   r   r   r   rW   0  s    zParameter.maxc                 C   s   | j |f| _dS )z#Set a maximum value of a parameter.N)rV   r7   rz   r   r   r   rW   6  s    c                 C   s   | fdd„}|S )aS  
        Used as a decorator to set the validator method for a `Parameter`.
        The validator method validates any value set for that parameter.
        It takes two arguments--``self``, which refers to the `Model`
        instance (remember, this is a method defined on a `Model`), and
        the value being set for this parameter.  The validator method's
        return value is ignored, but it may raise an exception if the value
        set on the parameter is invalid (typically an `InputParameterError`
        should be raised, though this is not currently a requirement).

        c                 S   s   t | ƒr| |_|S tdƒ‚d S )NzŠThis decorator method expects a callable.
The use of this method as a direct validator is
deprecated; use the new validate method instead
)rƒ   rM   r   )Úfuncr&   r   r   r   Ú	validatorJ  s    ÿz&Parameter.validator.<locals>.validatorr   )r&   rˆ   r   r   r   rˆ   <  s    zParameter.validatorc                 C   s&   | j dk	r"| jdk	r"|   | j|¡ dS )z#Run the validator on this parameterN)rM   r=   rz   r   r   r   ÚvalidateW  s    zParameter.validatec                 C   s|   t ƒ  ¡ }|d= | ¡ D ]V\}}|dkr|dkr4qn2t| |ƒrJt| |ƒ}nt| d| ƒrft| d| ƒ}|||< q| jf |ŽS )aÄ  
        Make a copy of this `Parameter`, overriding any of its core attributes
        in the process (or an exact copy).

        The arguments to this method are the same as those for the `Parameter`
        initializer.  This simply returns a new `Parameter` instance with any
        or all of the attributes overridden, and so returns the equivalent of:

        .. code:: python

            Parameter(self.name, self.description, ...)

        r&   N)rV   rW   Ú_)ÚlocalsÚcopyÚitemsÚhasattrrr   r\   )r&   rQ   rR   rS   r$   rT   rU   r5   r6   rV   rW   r7   rX   rY   Úkwargsrd   r    r   r   r   rŒ   \  s    


zParameter.copyc                 C   s   | j S )z4Return the model this  parameter is associated with.)r=   ru   r   r   r   ÚmodelŒ  s    zParameter.modelc                 C   sJ   || _ |  | j|¡| _|  | j|¡| _| jrF| jd k	r@| j| _nd | _d S r"   )r=   r?   r@   rA   r>   rD   r    rH   rz   r   r   r   r�   ‘  s    

c                 C   s   | j r| jS | jS )ac  
        Currently for internal use only.

        Like Parameter.value but does not pass the result through
        Parameter.getter.  By design this should only be used from bound
        parameters.

        This will probably be removed are retweaked at some point in the
        process of rethinking how parameter values are stored/updated.
        )r@   rx   r    ru   r   r   r   Ú
_raw_valueœ  s    zParameter._raw_valuec                 C   sŠ   t |tjƒr |jdkr†tdƒ‚nf|dkr,dS t|ƒ\}}t|ƒ}|dkrJn<|dkr~d| _|dk	r†|d j}t	j
|f||iŽ}ntdƒ‚|S )aL  Wraps a getter/setter function to support optionally passing in
        a reference to the model object as the second argument.
        If a model is tied to this parameter and its getter/setter supports
        a second argument then this creates a partial function using the model
        instance as the second argument.
        r   zOA numpy.ufunc used for Parameter getter/setter may only take one input argumentNé   TzIParameter getter/setter must be a function of either one or two arguments)r   r   ZufuncZninr   r   rc   r>   rQ   r.   Úpartial)r&   r,   r�   ÚinputsrŠ   ÚnargsZ	model_argr   r   r   r?   ¬  s(    
ÿ
ÿzParameter._create_value_wrapperc                 C   s0   t j| j|d�}| jd k	r,t|| jddd�}|S )Nr   FT)rŒ   Zsubok)r   Zasarrayr    r$   r   )r&   r   Zarrr   r   r   Ú	__array__Ó  s    
zParameter.__array__c                 C   s   t t | j¡ƒS r"   )r   r   Úallr    ru   r   r   r   Ú__bool__Ü  s    zParameter.__bool__T)r+   )r8   r8   NNNNFFNNNNNF)F)NNNNNNFFNNNNN)N)Jr   r   r   r   rq   r<   r_   rb   re   rk   rt   ÚpropertyrQ   rS   r    rU   r$   rF   rw   r}   r`   r~   r€   rX   rY   r5   r6   r7   rV   rW   rˆ   r‰   rŒ   r�   r‘   r?   r–   r˜   r0   ÚoperatorÚaddÚ__add__Ú__radd__ÚsubÚ__sub__Ú__rsub__ÚmulÚ__mul__Ú__rmul__ÚpowÚ__pow__Ú__rpow__ÚtruedivÚ__truediv__Ú__rtruediv__r3   ÚeqÚ__eq__ÚneÚ__ne__ÚltÚ__lt__ÚgtÚ__gt__ÚleÚ__le__ÚgeÚ__ge__r4   ÚnegÚ__neg__ÚabsÚ__abs__Ú__classcell__r   r   r[   r   r   r   sú   G              ñJ






















	







             ò
0



'
	











c                 C   s(   t | jƒ}| jdk	r$|› d| j›�}|S )z„
    Like array_repr_oneline but works on `Parameter` objects and supports
    rendering parameters with units like quantities.
    Nú )r   r    r$   )ÚparamÚoutr   r   r   Úparam_repr_onelineó  s    

r¾   )F)r   r.   r   rš   Únumpyr   Zastropy.unitsr   r   Zastropy.utilsr   Úutilsr   r   Ú__all__Ú	Exceptionr
   r   r	   r   r!   r0   r3   r4   r   r¾   r   r   r   r   Ú<module>   s,   
"
     