
    HR-e
                       d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
 ddlZddlmZ ddlmZ dd	gZ ed
d          Z G d de          Ze                    ej         ej        f          ZddZddZ G d dej                  Z G d de          Z edd          Z G d de          Z G d de          Z G d d	e          Z dS )z5
This module is to contain an improved bounding box.
    )annotationsN)
namedtuple)AnyCallableQuantity)
isiterableModelBoundingBoxCompoundBoundingBox_BaseIntervalzlower upperc                  n    e Zd ZdZd Zd Zed             Zed             Z	ed             Z
dd	Zd
 ZdS )	_Intervala  
    A single input's bounding box interval.

    Parameters
    ----------
    lower : float
        The lower bound of the interval

    upper : float
        The upper bound of the interval

    Methods
    -------
    validate :
        Constructs a valid interval

    outside :
        Determine which parts of an input array are outside the interval.

    domain :
        Constructs a discretization of the points inside the interval.
    c                (    d| j          d| j         dS )NzInterval(lower=z, upper=))lowerupperselfs    =lib/python3.11/site-packages/astropy/modeling/bounding_box.py__repr__z_Interval.__repr__2   s    BBBTZBBBB    c                *    t          j        |           S N)copydeepcopyr   s    r   r   z_Interval.copy5   s    }T"""r   c                   d}	 t          j        |           }nu# t          $ rh 	 t          |           dk    r| d         } t          j        d | D                       }n*# t          t          t
          f$ r t	          |          w xY wY nw xY w|dv }|s8t          |          dk    o$|d         dk    ot          d | D                       }t          |           r|st	          |          dS )	z1Validate the shape of an interval representation.z5An interval must be some sort of sequence of length 2   r   c                6    g | ]}|                                 S  )to_value.0bs     r   
<listcomp>z-_Interval._validate_shape.<locals>.<listcomp>D   s     !A!A!A1!**,,!A!A!Ar   ))   )r   r%   )r%   r   r%   c              3  J   K   | ]}t          |t          j                  V  d S r   )
isinstancenpndarrayr!   s     r   	<genexpr>z,_Interval._validate_shape.<locals>.<genexpr>M   s.      DDa
1bj11DDDDDDr   N)r(   shape	TypeErrorlen
ValueErrorAttributeErrorallr	   )intervalMESSAGEr+   valid_shapes       r   _validate_shapez_Interval._validate_shape8   s:    N		*HX&&EE 	* 	* 	**x==A%%'{H!A!A!A!A!ABB	>: * * * )))* 	* 55 	E

Q E!HMEDD8DDDDD  (## 	&; 	&W%%%	& 	&s&    
B9AB'BB
Bc                    t          j        |          t          j        |          k                                    r!t          j        d| d| dt
                      | ||          S )zGValidate the bounds are reasonable and construct an interval from them.zInvalid interval: upper bound z# is strictly less than lower bound .)r(   
asanyarrayr0   warningswarnRuntimeWarning)clsr   r   s      r   _validate_boundsz_Interval._validate_boundsS   s     M%  2=#7#77<<>> 	M> > >5:> > >   s5%   r   c                    |                      |           t          |          dk    rt          |d                   }nt          |          }|                     |d         |d                   S )z
        Construct and validate an interval.

        Parameters
        ----------
        interval : iterable
            A representation of the interval.

        Returns
        -------
        A validated interval.
        r   r   )r4   r-   tupler<   )r;   r1   s     r   validatez_Interval.validate_   se     	H%%%x==AXa[))HHXH##HQK!===r   _input
np.ndarrayc                P    t          j        || j        k     || j        k              S )aU  
        Parameters
        ----------
        _input : np.ndarray
            The evaluation input in the form of an array.

        Returns
        -------
        Boolean array indicating which parts of _input are outside the interval:
            True  -> position outside interval
            False -> position inside  interval
        )r(   
logical_orr   r   )r   r@   s     r   outsidez_Interval.outsidev   s$     }Vdj0&4:2EFFFr   c                H    t          j        | j        | j        |z   |          S r   )r(   aranger   r   )r   
resolutions     r   domainz_Interval.domain   s    yTZ*%<jIIIr   N)r@   rA   )__name__
__module____qualname____doc__r   r   staticmethodr4   classmethodr<   r?   rD   rH   r   r   r   r   r      s         .C C C# # # & & \&4 	! 	! [	! > > [>,G G G GJ J J J Jr   r   returnintc                   t          |t                    r?|| j        v r| j                            |          }nt	          d| d| j         d          t          j        t          |          t
          j                  rMd|cxk    rt          | j                  k     rn n|}n;t          d| dt          | j                   d          t	          d| d          |S )	z
    Get the input index corresponding to the given key.
        Can pass in either:
            the string name of the input or
            the input index itself.
    'z' is not one of the inputs: r6   r   zInteger key: z must be non-negative and < zKey value: z must be string or integer.)r'   strinputsindexr.   r(   
issubdtypetypeintegerr-   
IndexError)modelkeyrU   s      r   	get_indexr\      s    #s I%,L&&s++EEQQQ%,QQQRRR	tCyy"*	-	- I''''c%,'''''''EEUUUU\ARARUUU   GsGGGHHHLr   rU   c                    | j         |         S z4Get the input name corresponding to the input index.)rT   )rZ   rU   s     r   get_namer_      s    <r   c                  Z   e Zd ZdZd*d+dZed	             Zed,d            Zed-d            Zd.d/dZ	d0dZ
d1dZed2d            Zd3dZd Zej        d4d            Zej        d5d            Zed             Zd Zd Zd Zd  Zed6d#            Zd7d&Zd7d'Zed(             Zd8d)ZdS )9_BoundingDomaina  
    Base class for ModelBoundingBox and CompoundBoundingBox.
        This is where all the `~astropy.modeling.core.Model` evaluation
        code for evaluating with a bounding box is because it is common
        to both types of bounding box.

    Parameters
    ----------
    model : `~astropy.modeling.Model`
        The Model this bounding domain is for.

    prepare_inputs :
        Generates the necessary input information so that model can
        be evaluated only for input points entirely inside bounding_box.
        This needs to be implemented by a subclass. Note that most of
        the implementation is in ModelBoundingBox.

    prepare_outputs :
        Fills the output values in for any input points outside the
        bounding_box.

    evaluate :
        Performs a complete model evaluation while enforcing the bounds
        on the inputs and returns a complete output.
    NCignored	list[int]orderrS   c                |    || _         |                     |          | _        |                     |          | _        d S r   )_model_validate_ignored_ignored
_get_order_order)r   rZ   rc   re   s       r   __init__z_BoundingDomain.__init__   s5    ..w77ooe,,r   c                    | j         S r   )rg   r   s    r   rZ   z_BoundingDomain.model   
    {r   rO   c                    | j         S r   )rk   r   s    r   re   z_BoundingDomain.order   rn   r   c                    | j         S r   ri   r   s    r   rc   z_BoundingDomain.ignored   s
    }r   c                F    || j         }|dvrt          d| d          |S )zd
        Get if bounding_box is C/python ordered or Fortran/mathematically
        ordered.
        N)rb   FzTorder must be either 'C' (C/python order) or 'F' (Fortran/mathematical order), got: r6   )rk   r.   )r   re   s     r   rj   z_BoundingDomain._get_order   sO    
 =KE
""C:?C C C  
 r   rP   c                ,    t          | j        |          S )z
        Get the input index corresponding to the given key.
            Can pass in either:
                the string name of the input or
                the input index itself.
        )r\   rg   r   r[   s     r   
_get_indexz_BoundingDomain._get_index   s     c***r   rU   c                ,    t          | j        |          S r^   )r_   rg   )r   rU   s     r   	_get_namez_BoundingDomain._get_name   s    U+++r   	list[str]c                *      fd j         D             S )Nc                :    g | ]}                     |          S r   rx   )r"   rU   r   s     r   r$   z2_BoundingDomain.ignored_inputs.<locals>.<listcomp>   s%    AAA%u%%AAAr   rq   r   s   `r   ignored_inputsz_BoundingDomain.ignored_inputs   s    AAAA4=AAAAr   listc                (     |g S  fd|D             S )Nc                :    g | ]}                     |          S r   rv   )r"   r[   r   s     r   r$   z5_BoundingDomain._validate_ignored.<locals>.<listcomp>   s%    <<<SDOOC((<<<r   r   )r   rc   s   ` r   rh   z!_BoundingDomain._validate_ignored   s'    ?I<<<<G<<<<r   c                     t          d          )NzPThis bounding box is fixed by the model and does not have adjustable parameters.NotImplementedError)r   argskwargss      r   __call__z_BoundingDomain.__call__   s    !%
 
 	
r   fixed_inputsdictc                     t          d          )C  
        Fix the bounding_box for a `fix_inputs` compound model.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The new model for which this will be a bounding_box
        fixed_inputs : dict
            Dictionary of inputs which have been fixed by this bounding box.
        z,This should be implemented by a child class.r   )r   rZ   r   s      r   
fix_inputsz_BoundingDomain.fix_inputs  s     ""PQQQr   tuple[Any, Any, Any]c                     t          d          )|  
        Get prepare the inputs with respect to the bounding box.

        Parameters
        ----------
        input_shape : tuple
            The shape that all inputs have be reshaped/broadcasted into
        inputs : list
            List of all the model inputs

        Returns
        -------
        valid_inputs : list
            The inputs reduced to just those inputs which are all inside
            their respective bounding box intervals
        valid_index : array_like
            array of all indices inside the bounding box
        all_out: bool
            if all of the inputs are outside the bounding_box
        z1This has not been implemented for BoundingDomain.r   )r   input_shaperT   s      r   prepare_inputsz_BoundingDomain.prepare_inputs  s    , ""UVVVr   c                0    t          j        |           |z   S )a  
        Create a baseline output, assuming that the entire input is outside
        the bounding box.

        Parameters
        ----------
        input_shape : tuple
            The shape that all inputs have be reshaped/broadcasted into
        fill_value : float
            The value which will be assigned to inputs which are outside
            the bounding box

        Returns
        -------
        An array of the correct shape containing all fill_value
        )r(   zeros)r   
fill_values     r   _base_outputz_BoundingDomain._base_output*  s    $ x$$z11r   c                Z      fdt           j        j                  D             dfS )a  
        Create output if all inputs are outside the domain.

        Parameters
        ----------
        input_shape : tuple
            The shape that all inputs have be reshaped/broadcasted into
        fill_value : float
            The value which will be assigned to inputs which are outside
            the bounding box

        Returns
        -------
        A full set of outputs for case that all inputs are outside domain.
        c                <    g | ]}                               S r   )r   )r"   _r   r   r   s     r   r$   z3_BoundingDomain._all_out_output.<locals>.<listcomp>N  s9     
 
 
 k:66
 
 
r   N)rangerg   	n_outputs)r   r   r   s   ```r   _all_out_outputz_BoundingDomain._all_out_output>  sQ     
 
 
 
 
 
4;011
 
 
  	r   c                    |                      ||          }|j        st          j        |          }n|||<   t          j        |          r|                    d          }|S )a
  
        For a single output fill in all the parts corresponding to inputs
        outside the bounding box.

        Parameters
        ----------
        valid_output : numpy array
            The output from the model corresponding to inputs inside the
            bounding box
        valid_index : numpy array
            array of all indices of inputs inside the bounding box
        input_shape : tuple
            The shape that all inputs have be reshaped/broadcasted into
        fill_value : float
            The value which will be assigned to inputs which are outside
            the bounding box

        Returns
        -------
        An output array with all the indices corresponding to inputs
        outside the bounding box filled in by fill_value
        r   )r   r+   r(   arrayisscalaritem)r   valid_outputvalid_indexr   r   outputs         r   _modify_outputz_BoundingDomain._modify_outputS  sd    . "";
;;| 	/Xl++FF".F;;|$$ 	$[[^^Fr   c           	     j    g }|D ]-}|                     |                     ||||                     .|S )a  
        Fill in all the outputs of the model corresponding to inputs
        outside the bounding_box.

        Parameters
        ----------
        valid_outputs : list of numpy array
            The list of outputs from the model corresponding to inputs
            inside the bounding box
        valid_index : numpy array
            array of all indices of inputs inside the bounding box
        input_shape : tuple
            The shape that all inputs have be reshaped/broadcasted into
        fill_value : float
            The value which will be assigned to inputs which are outside
            the bounding box

        Returns
        -------
        List of filled in output arrays.
        )appendr   )r   valid_outputsr   r   r   outputsr   s          r   _prepare_outputsz _BoundingDomain._prepare_outputsu  sQ    , ) 	 	LNN##L+{JWW    r   c                X    | j         j        dk    r|g}|                     ||||          S )a  
        Fill in all the outputs of the model corresponding to inputs
        outside the bounding_box, adjusting any single output model so that
        its output becomes a list of containing that output.

        Parameters
        ----------
        valid_outputs : list
            The list of outputs from the model corresponding to inputs
            inside the bounding box
        valid_index : array_like
            array of all indices of inputs inside the bounding box
        input_shape : tuple
            The shape that all inputs have be reshaped/broadcasted into
        fill_value : float
            The value which will be assigned to inputs which are outside
            the bounding box
        r   )rg   r   r   )r   r   r   r   r   s        r   prepare_outputsz_BoundingDomain.prepare_outputs  s<    & ; A%%*OM$$;Z
 
 	
r   
with_unitsboolc                ,    |rt          | dd          S dS )aD  
        Get the unit for outputs if one is required.

        Parameters
        ----------
        valid_outputs : list of numpy array
            The list of outputs from the model corresponding to inputs
            inside the bounding box
        with_units : bool
            whether or not a unit is required
        unitN)getattr)r   r   s     r   _get_valid_outputs_unitz'_BoundingDomain._get_valid_outputs_unit  s(      	8=&$777	8 	8r   evaluater   c                x     ||          }|                      ||          }|                     ||||          |fS )a  
        Evaluate the model using the given evaluate routine.

        Parameters
        ----------
        evaluate : Callable
            callable which takes in the valid inputs to evaluate model
        valid_inputs : list of numpy arrays
            The inputs reduced to just those inputs which are all inside
            their respective bounding box intervals
        valid_index : numpy array
            array of all indices inside the bounding box
        input_shape : tuple
            The shape that all inputs have be reshaped/broadcasted into
        fill_value : float
            The value which will be assigned to inputs which are outside
            the bounding box
        with_units : bool
            whether or not a unit is required

        Returns
        -------
        outputs :
            list containing filled in output values
        valid_outputs_unit :
            the unit that will be attached to the outputs
        )r   r   )	r   r   valid_inputsr   r   r   r   r   valid_outputs_units	            r   _evaluate_modelz_BoundingDomain._evaluate_model  sP    H !..!99-TT   [*UU
 	
r   c                    |                      ||          \  }}}|r|                     ||          S |                     ||||||          S )a  Evaluate model with steps: prepare_inputs -> evaluate -> prepare_outputs.

        Parameters
        ----------
        evaluate : Callable
            callable which takes in the valid inputs to evaluate model
        valid_inputs : list of numpy arrays
            The inputs reduced to just those inputs which are all inside
            their respective bounding box intervals
        valid_index : numpy array
            array of all indices inside the bounding box
        input_shape : tuple
            The shape that all inputs have be reshaped/broadcasted into
        fill_value : float
            The value which will be assigned to inputs which are outside
            the bounding box
        with_units : bool
            whether or not a unit is required

        Returns
        -------
        outputs :
            list containing filled in output values
        valid_outputs_unit :
            the unit that will be attached to the outputs
        )r   r   r   )	r   r   rT   r   r   r   r   r   all_outs	            r   	_evaluatez_BoundingDomain._evaluate  sc    : .2-@-@f-U-U*k7 	''Z@@@'',[*j  r   c                0    |t          | |dd          S | S )a  
        Set the units on the outputs
            prepare_inputs -> evaluate -> prepare_outputs -> set output units.

        Parameters
        ----------
        outputs :
            list containing filled in output values
        valid_outputs_unit :
            the unit that will be attached to the outputs

        Returns
        -------
        List containing filled in output values and units
        NFT)r   subokr   )r   r   s     r   _set_outputs_unitz!_BoundingDomain._set_outputs_unit  s'    " )G%7e4PPPPr   c                    | j                             |          }|                     ||||| j         j                  \  }}t	          |                     ||                    S )a  
        Perform full model evaluation steps:
            prepare_inputs -> evaluate -> prepare_outputs -> set output units.

        Parameters
        ----------
        evaluate : callable
            callable which takes in the valid inputs to evaluate model
        valid_inputs : list
            The inputs reduced to just those inputs which are all inside
            their respective bounding box intervals
        valid_index : array_like
            array of all indices inside the bounding box
        fill_value : float
            The value which will be assigned to inputs which are outside
            the bounding box
        )rg   r   r   bbox_with_unitsr>   r   )r   r   rT   r   r   r   r   s          r   r   z_BoundingDomain.evaluate%  se    $ k--f55
 '+nnfk:t{7R'
 '
## T++G5GHHIIIr   Nrb   )rc   rd   re   rS   rO   rS   )rO   rd   r   )re   rS   rO   rS   rO   rP   rU   rP   )rO   ry   )rc   r~   rO   rd   r   r   rO   r   )r   r   )r   r   r   r   )r   r   )rI   rJ   rK   rL   rl   propertyrZ   re   rc   rj   rv   rx   r}   rh   r   abcabstractmethodr   r   rM   r   r   r   r   r   r   r   r   r   r   r   r   r   ra   ra      sA        4- - - - -
   X    X    X     + + + +, , , , B B B XB= = = =
 
 
 	R R R R 	W W W W. 2 2 \2&  *     D  <
 
 
4 8 8 8 \8*
 *
 *
 *
X$ $ $ $L   \*J J J J J Jr   ra   c                  N    e Zd ZdZ	 	 d/d0 fd
Zd1dZed2d            Zed3d            Zd Z	d Z
d Zd Zd Zd1d4dZd Zd Zd Zd5dZed             Zd1d4dZed6d            Zd1d4d Zd1d4d!Ze	 	 	 d7d8d&            Zd9d:d(Zed)             Zd1d4d*Zd+ Zd, Zd;d.Z xZ S )<r
   a  
    A model's bounding box.

    Parameters
    ----------
    intervals : dict
        A dictionary containing all the intervals for each model input
            keys   -> input index
            values -> interval for that index

    model : `~astropy.modeling.Model`
        The Model this bounding_box is for.

    ignored : list
        A list containing all the inputs (index) which will not be
        checked for whether or not their elements are in/out of an interval.

    order : optional, str
        The ordering that is assumed for the tuple representation of this
        bounding_box. Options: 'C': C/Python order, e.g. z, y, x.
        (default), 'F': Fortran/mathematical notation order, e.g. x, y, z.
    Nrb   	intervalsdict[int, _Interval]rc   rd   re   rS   c                    t                                          |||           i | _        |dk    r|i k    r|                     ||           d S d S d S )Nr   re   )superrl   
_intervals	_validate)r   r   rZ   rc   re   	__class__s        r   rl   zModelBoundingBox.__init__Z  s`     	///??yBNN9EN22222 ?r   c                    d | j                                         D             }|| j                                        }t	          || j        || j                  S )Nc                >    i | ]\  }}||                                 S r   )r   )r"   rU   r1   s      r   
<dictcomp>z)ModelBoundingBox.copy.<locals>.<dictcomp>h  s3     
 
 
'6uhE8==??
 
 
r   rc   re   )r   itemsri   r   r
   rg   rk   )r   rc   r   s      r   r   zModelBoundingBox.copyg  sl    
 
:>/:O:O:Q:Q
 
 
	 ?m((**Gt{G4;
 
 
 	
r   rO   c                    | j         S )z2Return bounding_box labeled using input positions.)r   r   s    r   r   zModelBoundingBox.intervalss  s     r   dict[str, _Interval]c                N      fd j                                         D             S )z.Return bounding_box labeled using input names.c                B    i | ]\  }}                     |          |S r   r|   )r"   rU   bboxr   s      r   r   z4ModelBoundingBox.named_intervals.<locals>.<dictcomp>{  s+    WWWtu%%tWWWr   )r   r   r   s   `r   named_intervalsz ModelBoundingBox.named_intervalsx  s.     XWWWt?T?T?V?VWWWWr   c                   ddg}| j                                         D ] \  }}|                    d| d|            !|                    d           t          | j                  dk    r|                    d| j                    |                    d| j        j        j         d	| j        j	         d
           |                    d| j
         d           |                    d
           d                    |          S )NzModelBoundingBox(z    intervals={        z:     }r   z    ignored=z
    model=z(inputs=r   z    order='rR   
)r   r   r   r-   ri   r}   rg   r   rI   rT   rk   join)r   partsnamer1   s       r   r   zModelBoundingBox.__repr__}  s   $&78"288:: 	8 	8ND(LL6D66H667777Wt}!!LL=(;==>>>V.7VVASVVV	
 	
 	
 	14;111222Syyr   c                *    t          | j                  S r   )r-   r   r   s    r   __len__zModelBoundingBox.__len__  s    4?###r   c                z    	 |                      |          | j        v p| j        S # t          t          f$ r Y dS w xY wNF)rv   r   ri   rY   r.   ru   s     r   __contains__zModelBoundingBox.__contains__  sN    	??3''4?:KdmKJ' 	 	 	55	s   "% ::c                :    |                      |          | j        v S r   )rv   r   ru   s     r   has_intervalzModelBoundingBox.has_interval  s    s##t66r   c                    |                      |          }|| j        v rt          S | j        |                      |                   S )z=Get bounding_box entries by either input name or input index.)rv   ri   _ignored_intervalr   r   r[   rU   s      r   __getitem__zModelBoundingBox.__getitem__  s?    $$DM!!$$?4??3#7#788r   c                z    t           j                  dk    r9t          t           j                                                  d                   S                      |          } j        j        }|dk    r|ddd         }t           fd|D                       }t          |          dk    r|d         }|S )z
        Return the old tuple of tuples representation of the bounding_box
            order='C' corresponds to the old bounding_box ordering
            order='F' corresponds to the gwcs bounding_box ordering.
        r   r   rb   Nc              3  B   K   | ]}t          |                   V  d S r   r>   )r"   
input_namer   s     r   r*   z0ModelBoundingBox.bounding_box.<locals>.<genexpr>  s0      JJZtJ/00JJJJJJr   )r-   r   r>   r~   valuesrj   rg   rT   )r   re   rT   r   s   `   r   bounding_boxzModelBoundingBox.bounding_box  s     t1$$do446677:;;;OOE**E['F||"JJJJ6JJJJJD4yyA~~AwKr   c                    t          |t                    r|                                 |k    S t          |t                    r | j        |j        k    o| j        |j        k    S dS )z?Note equality can be either with old representation or new one.F)r'   r>   r   r
   r   rc   r   values     r   __eq__zModelBoundingBox.__eq__  sg    eU## 	$$&&%///00 	Neo5 - 5r   c                    |                      |          }|| j        v r| j                            |           t                              |          | j        |<   dS )zBValidate and store interval under key (input index or input name).N)rv   ri   remover   r?   r   )r   r[   r   rU   s       r   __setitem__zModelBoundingBox.__setitem__  sV    $$DM!!M  '''!*!3!3E!:!:r   c                    |                      |          }|| j        v rt          d| d          | j        |= | j                            |           dS )zDelete stored interval.zCannot delete ignored input: !N)rv   ri   RuntimeErrorr   r   r   s      r   __delitem__zModelBoundingBox.__delitem__  s`    $$DM!!EsEEEFFFOE"U#####r   r   r   c                D    |                                 D ]
\  }}|| |<   dS )z:Validate passing dictionary of intervals and setting them.Nr   )r   r   r[   r   s       r   _validate_dictzModelBoundingBox._validate_dict  s6    &,,.. 	 	JCDII	 	r   c                P      fd j         j        D             } fd|D             S )Nc                :    g | ]}                     |          S r   r   r"   r@   r   s     r   r$   z;ModelBoundingBox._available_input_index.<locals>.<listcomp>  s%    VVVT__V44VVVr   c                &    g | ]}|j         v|S r   rq   r  s     r   r$   z;ModelBoundingBox._available_input_index.<locals>.<listcomp>  s%    VVV6&:U:U:U:U:Ur   )rg   rT   )r   model_input_indexs   ` r   _available_input_indexz'ModelBoundingBox._available_input_index  s=    VVVV4;CUVVVVVVV%6VVVVr   c                    |                      |          }|dk    r|ddd         }t          |          D ]\  }}|| | j        |         <   dS )z`
        Validate passing tuple of tuples representation (or related) and setting them.
        rb   Nr   )rj   	enumerater  )r   r   re   rU   r   s        r   _validate_sequencez#ModelBoundingBox._validate_sequence  sj     &&C<< ("-L%l33 	= 	=LE57<D,U344	= 	=r   rP   c                X    | j         j        t          | j                  z
  }|dk    r|S dS )Nr   )rg   n_inputsr-   ri   )r   r  s     r   	_n_inputszModelBoundingBox._n_inputs  s.    ;'#dm*<*<<a<<O1r   c                
   t          |          | j        k    r(t          dt          |           d| j         d          t          |t                    r|                     |           dS |                     ||           dS )z-Validate and set any iterable representation.zFound z" intervals, but must have exactly r6   N)r-   r  r.   r'   r   r  r
  r   r   re   s      r   _validate_iterablez#ModelBoundingBox._validate_iterable  s    |..;\** ; ;)-; ; ;  
 lD)) 	9-----##L%88888r   c                    | j         dk    r't          |t                    s|| | j        d         <   dS |                     ||           dS )z$Validate and set any representation.r   r   N)r  r'   r   r  r  r  s      r   r   zModelBoundingBox._validate  sR    >Qz,'E'E3?D,Q/000##L%88888r   Fr~   _preserve_ignorer   c                    t          |t                    r|j        }|r|j        }|j        } | i |||          }|                    |           |S )a  
        Construct a valid bounding box for a model.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The model for which this will be a bounding_box
        bounding_box : dict, tuple
            A possible representation of the bounding box
        order : optional, str
            The order that a tuple representation will be assumed to be
                Default: 'C'
        r   )r'   r
   re   rc   r   r   )r;   rZ   r   rc   re   r  r   news           r   r?   zModelBoundingBox.validate  sf    . l$455 	8 &E /&.'7Lc"eWE:::l###
r   r   c                    |                                  }|                                D ]}||= |r|j        }nd}t                              ||j        ||j                  S )a  
        Fix the bounding_box for a `fix_inputs` compound model.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The new model for which this will be a bounding_box
        fixed_inputs : dict
            Dictionary of inputs which have been fixed by this bounding box.
        keep_ignored : bool
            Keep the ignored inputs of the bounding box (internal argument only)
        Nr   )r   keysrc   r
   r?   r   rk   )r   rZ   r   _keep_ignoredr  r@   rc   s          r   r   zModelBoundingBox.fix_inputs(  sv     iikk"'')) 	 	FF 	kGGG((3&sz ) 
 
 	
r   c                     t          |           S r   )r-   r   s    r   	dimensionzModelBoundingBox.dimensionC  s    4yyr   c                      j         j        }                     |          }|dk    r|d d d         } fd|D             S )Nrb   r   c                F    g | ]}|                                        S r   )rH   )r"   r   rG   r   s     r   r$   z+ModelBoundingBox.domain.<locals>.<listcomp>M  s,    MMM
Z ''
33MMMr   )rg   rT   rj   )r   rG   re   rT   s   ``  r   rH   zModelBoundingBox.domainG  sT    #&&C<<DDbD\FMMMMMfMMMMr   c                ,   d}t          j        |t                    }t          |          D ]d\  }}t          j        |          }t          j        | |                             |          |          }d||<   |                                rd} ne||fS )a  
        Get all the input positions which are outside the bounding_box,
        so that the corresponding outputs can be filled with the fill
        value (default NaN).

        Parameters
        ----------
        input_shape : tuple
            The shape that all inputs have be reshaped/broadcasted into
        inputs : list
            List of all the model inputs

        Returns
        -------
        outside_index : bool-numpy array
            True  -> position outside bounding_box
            False -> position inside  bounding_box
        all_out : bool
            if all of the inputs are outside the bounding_box
        F)dtypeT)r(   r   r   r	  r7   broadcast_torD   r0   )r   r   rT   r   outside_indexrU   r@   rD   s           r   _outsidezModelBoundingBox._outsideO  s    * D999&v.. 	 	ME6]6**Fod5k&9&9&&A&A;OOG%)M'"  ""  g%%r   c                    |                      ||          \  }}t          j        t          j        |                                                    }t          |d                   dk    rd}||fS )a  
        Get the indices of all the inputs inside the bounding_box.

        Parameters
        ----------
        input_shape : tuple
            The shape that all inputs have be reshaped/broadcasted into
        inputs : list
            List of all the model inputs

        Returns
        -------
        valid_index : numpy array
            array of all indices inside the bounding box
        all_out : bool
            if all of the inputs are outside the bounding_box
        r   T)r   r(   
atleast_1dlogical_notnonzeror-   )r   r   rT   r  r   r   s         r   _valid_indexzModelBoundingBox._valid_indexs  sh    $ "&{F!C!CwmBN=$A$ABBJJLL{1~!##GG##r   r   c                p   |                      ||          \  }}g }|s|D ]}|rlt          j        t          j        |          |          |         }t          j        |          r|                    d          }|                    |           p|                    |           t          |          ||fS )r   r   )r%  r(   r  r"  r   r   r   r>   )r   r   rT   r   r   r   r@   valid_inputs           r   r   zModelBoundingBox.prepare_inputs  s    *  $00fEEW 
	0  	0 	0 0"$/"-2G2G"U"U##K {6** :&1&6&6q&9&9 ''4444 ''////\""K88r   r   )r   r   rc   rd   re   rS   r   )rO   r   )rO   r   )re   rS   )r   r   r   )Nrb   F)rc   r~   re   rS   r  r   )Fr   r   )!rI   rJ   rK   rL   rl   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r
  r  r  r   rN   r?   r   r  rH   r   r%  r   __classcell__r   s   @r   r
   r
   B  s        6 "3 3 3 3 3 3 3

 

 

 

    X X X X XX     $$ $ $  7 7 79 9 9    (	 	 	; ; ;$ $ $   
 W W XW
= = = = =    X9 9 9 9 99 9 9 9 9 
 !&    [B
 
 
 
 
6   XN N N N N"& "& "&H$ $ $4$9 $9 $9 $9 $9 $9 $9 $9r   _BaseSelectorArgumentzindex ignorec                  f     e Zd ZdZ fdZeddd            Zd Zdd
Zd Z	ddZ
ddZd Z xZS )_SelectorArgumenta#  
    Contains a single CompoundBoundingBox slicing input.

    Parameters
    ----------
    index : int
        The index of the input in the input list

    ignore : bool
        Whether or not this input will be ignored by the bounding box.

    Methods
    -------
    validate :
        Returns a valid SelectorArgument for a given model.

    get_selector :
        Returns the value of the input for use in finding the correct
        bounding_box.

    get_fixed_value :
        Gets the slicing value from a fix_inputs set of values.
    c                N    t                                          | ||          }|S r   )r   __new__)r;   rU   ignorer   r   s       r   r.  z_SelectorArgument.__new__  s!    wwsE622r   Trc   r   c                6     | t          ||          |          S )a  
        Construct a valid selector argument for a CompoundBoundingBox.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The model for which this will be an argument for.
        argument : int or str
            A representation of which evaluation input to use
        ignored : optional, bool
            Whether or not to ignore this argument in the ModelBoundingBox.

        Returns
        -------
        Validated selector_argument
        )r\   )r;   rZ   argumentrc   s       r   r?   z_SelectorArgument.validate  s     $ s9UH--w777r   c                    || j                  }t          |          r*t          |          dk    r|d         S t          |          S |S )z
        Get the selector value corresponding to this argument.

        Parameters
        ----------
        *inputs :
            All the processed model evaluation inputs.
        r   r   )rU   r	   r-   r>   r   rT   	_selectors      r   get_selectorz_SelectorArgument.get_selector  sO     4:&	i   	(9~~"" |#Y'''r   rO   rS   c                ,    t          || j                  S )z
        Get the name of the input described by this selector argument.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model this selector argument is for.
        )r_   rU   r   rZ   s     r   r   z_SelectorArgument.name  s     tz***r   c                D    d|                      |           d| j         dS )z
        Get a pretty-print representation of this object.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model this selector argument is for.
        zArgument(name='z
', ignore=r   r   r/  r7  s     r   pretty_reprz_SelectorArgument.pretty_repr  s,     L5!1!1KKT[KKKKr   r   r   c                    | j         |v r|| j                  S |                     |          |v r||                     |                   S t          |                     |           d|           )a  
        Gets the value fixed input corresponding to this argument.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model this selector argument is for.

        values : dict
            Dictionary of fixed inputs.
        z was not found in )rU   r   r   r:  r   rZ   r   s      r   get_fixed_valuez!_SelectorArgument.get_fixed_value  s}     :$*%%yy6))dii..//"''..JJ&JJ  r   c                4    | j         t          ||          k    S )a@  
        Determine if passed argument is described by this selector argument.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model this selector argument is for.

        argument : int or str
            A representation of which evaluation input is being used
        )rU   r\   r   rZ   r1  s      r   is_argumentz_SelectorArgument.is_argument&  s     zYuh7777r   c                :    |                      |          | j        fS )z
        Get a tuple representation of this argument using the input
        name from the model.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model this selector argument is for.
        r9  r7  s     r   named_tuplez_SelectorArgument.named_tuple4  s     		%  $+..r   )T)rc   r   r   r   r   rO   r   )rI   rJ   rK   rL   r.  rN   r?   r5  r   r:  r=  r@  rB  r(  r)  s   @r   r,  r,    s         0    
 8 8 8 8 [8&  "	+ 	+ 	+ 	+	L 	L 	L   ,8 8 8 8
/ 
/ 
/ 
/ 
/ 
/ 
/r   r,  c                       e Zd ZdZdZdd fdZd Zed	             Zed
             Z	e
ddd            Zd Zd ZddZddZd Zd Zd Zd Z xZS )_SelectorArgumentsa  
    Contains the CompoundBoundingBox slicing description.

    Parameters
    ----------
    input_ :
        The SelectorArgument values

    Methods
    -------
    validate :
        Returns a valid SelectorArguments for its model.

    get_selector :
        Returns the selector a set of inputs corresponds to.

    is_selector :
        Determines if a selector is correctly formatted for this CompoundBoundingBox.

    get_fixed_value :
        Gets the selector from a fix_inputs set of values.
    Ninput_tuple[_SelectorArgument]kept_ignorer~   c                n    t                                          | |          }|g |_        n||_        |S r   )r   r.  _kept_ignore)r;   rG  rI  r   r   s       r   r.  z_SelectorArguments.__new__[  s8    wwsF++ "D +Dr   c                    dg}| D ]-}|                     d|                    |                      .|                     d           d                    |          S )z
        Get a pretty-print representation of this object.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model these selector arguments are for.
        zSelectorArguments(z    r   r   )r   r:  r   )r   rZ   r   r1  s       r   r:  z_SelectorArguments.pretty_repre  sk     && 	? 	?HLL= 4 4U ; ;==>>>>Syyr   c                R    d | D             }|                     | j                   |S )zGet the list of ignored inputs.c                *    g | ]}|j         	|j        S r   )r/  rU   )r"   r1  s     r   r$   z-_SelectorArguments.ignore.<locals>.<listcomp>x  s!    IIIXI(.IIIr   )extendrK  )r   r/  s     r   r/  z_SelectorArguments.ignoreu  s2     JIIIId'(((r   c                    | j         S )z%The arguments to persist in ignoring.)rK  r   s    r   rI  z_SelectorArguments.kept_ignore}  s       r   c                   g }|D ]b}t          j        |g|R  }|j        d |D             v r&t          dt	          ||j                   d          |                    |           ct          |          dk    rt          d          t          |t                    r|g }|	                    |j
                    | t          |          |          S )ad  
        Construct a valid Selector description for a CompoundBoundingBox.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model these selector arguments are for.

        arguments :
            The individual argument information

        kept_ignore :
            Arguments to persist as ignored
        c                    g | ]	}|j         
S r   )rU   )r"   thiss     r   r$   z/_SelectorArguments.validate.<locals>.<listcomp>  s    >>>t
>>>r   zInput: 'z' has been repeated.r   z-There must be at least one selector argument.)r,  r?   rU   r.   r_   r   r-   r'   rF  rO  rI  r>   )r;   rZ   	argumentsrI  rT   r1  r@   s          r   r?   z_SelectorArguments.validate  s      ! 	" 	"H&/AAAAF|>>v>>>>> Rxv|<<RRR   MM&!!!!v;;!LMMMi!344 	6" y4555s5==+...r   c                :    t          fd| D                       S )z
        Get the selector corresponding to these inputs.

        Parameters
        ----------
        *inputs :
            All the processed model evaluation inputs.
        c              3  ,   K   | ]} |j          V  d S r   )r5  )r"   r1  rT   s     r   r*   z2_SelectorArguments.get_selector.<locals>.<genexpr>  s.      II*X*F3IIIIIIr   r   )r   rT   s    `r   r5  z_SelectorArguments.get_selector  s(     IIIIDIIIIIIr   c                l    t          |t                    ot          |          t          |           k    S )z
        Determine if this is a reasonable selector.

        Parameters
        ----------
        _selector : tuple
            The selector to check
        )r'   r>   r-   r   r4  s     r   is_selectorz_SelectorArguments.is_selector  s*     )U++KI#d))0KKr   r   r   c                >    t          fd| D                       S )a  
        Gets the value fixed input corresponding to this argument.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model these selector arguments are for.

        values : dict
            Dictionary of fixed inputs.
        c              3  D   K   | ]}|                               V  d S r   )r=  )r"   r1  rZ   r   s     r   r*   z6_SelectorArguments.get_fixed_values.<locals>.<genexpr>  s3      RRX--eV<<RRRRRRr   r   r<  s    ``r   get_fixed_valuesz#_SelectorArguments.get_fixed_values  s,     RRRRRTRRRRRRr   rO   r   c                >    t          fd| D                       S )a=  
        Determine if passed argument is one of the selector arguments.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model these selector arguments are for.

        argument : int or str
            A representation of which evaluation input is being used
        c              3  D   K   | ]}|                               V  d S r   )r@  )r"   selector_argr1  rZ   s     r   r*   z1_SelectorArguments.is_argument.<locals>.<genexpr>  s3      VV<++E8<<VVVVVVr   )anyr?  s    ``r   r@  z_SelectorArguments.is_argument  s-     VVVVVQUVVVVVVr   c                    t          |           D ]\  }}|                    ||          r|c S  t          | d          )a3  
        Get the index of the argument passed in the selector tuples.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model these selector arguments are for.

        argument : int or str
            A representation of which argument is being used
        z. does not correspond to any selector argument.)r	  r@  r.   )r   rZ   r1  rU   r_  s        r   selector_indexz!_SelectorArguments.selector_index  sd     $-T?? 	 	E<''x88  KKK  r   c                   t          |           }|                    |                     ||                    j        g}|                    | j                   t                              |t          |          |          S )a+  
        Reduce the selector arguments by the argument given.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model these selector arguments are for.

        argument : int or str
            A representation of which argument is being used
        )	r~   poprb  rU   rO  rK  rF  r?   r>   )r   rZ   r1  rT  rI  s        r   reducez_SelectorArguments.reduce  sm     JJ	 }}T%8%8%I%IJJPQ4,---!**5%	2B2BKPPPr   c                    |                      ||          rt          | d          t          ||          g}t                              || |          S )a  
        Add argument to the kept_ignore list.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model these selector arguments are for.

        argument : int or str
            A representation of which argument is being used
        z/: is a selector argument and cannot be ignored.)r@  r.   r\   rF  r?   )r   rZ   r1  rI  s       r   
add_ignorez_SelectorArguments.add_ignore  sf     E8,, 	LLL   !112!**5$DDDr   c                :    t          fd| D                       S )z
        Get a tuple of selector argument tuples using input names.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The Model these selector arguments are for.
        c              3  B   K   | ]}|                               V  d S r   )rB  )r"   r_  rZ   s     r   r*   z1_SelectorArguments.named_tuple.<locals>.<genexpr>  s1      NN\--e44NNNNNNr   r   r7  s    `r   rB  z_SelectorArguments.named_tuple  s(     NNNNNNNNNNr   r   )rG  rH  rI  r~   )rI  r~   rC  rD  )rI   rJ   rK   rL   rK  r.  r:  r   r/  rI  rN   r?   r5  rY  r\  r@  rb  re  rg  rB  r(  r)  s   @r   rF  rF  A  s[        . L               X ! ! X! !/ !/ !/ !/ [!/F	J 	J 	J	L 	L 	LS S S SW W W W  (Q Q Q$E E E*	O 	O 	O 	O 	O 	O 	Or   rF  c                  B    e Zd ZdZ	 	 	 d/d0 fdZd Zd Zed1d            Zed2d            Z	e	j
        d             Z	ed3d            Zed             Zed             Zd Zd4dZd Ze	 	 	 	 	 d5d6d"            Zd# Zd$ Zd% Zd7d'Zd8d)Zd1d*Zd+ Zd, Zd9d.Z xZS ):r   a  
    A model's compound bounding box.

    Parameters
    ----------
    bounding_boxes : dict
        A dictionary containing all the ModelBoundingBoxes that are possible
            keys   -> _selector (extracted from model inputs)
            values -> ModelBoundingBox

    model : `~astropy.modeling.Model`
        The Model this compound bounding_box is for.

    selector_args : _SelectorArguments
        A description of how to extract the selectors from model inputs.

    create_selector : optional
        A method which takes in the selector and the model to return a
        valid bounding corresponding to that selector. This can be used
        to construct new bounding_boxes for previously undefined selectors.
        These new boxes are then stored for future lookups.

    order : optional, str
        The ordering that is assumed for the tuple representation of the
        bounding_boxes.
    Nrb   bounding_boxesdict[Any, ModelBoundingBox]selector_argsrF  create_selectorr   rc   rd   re   rS   c                    t                                          |||           || _        t                              ||          | _        i | _        |                     |           d S r   )r   rl   _create_selectorrF  r?   _selector_args_bounding_boxesr   )r   rk  rZ   rm  rn  rc   re   r   s          r   rl   zCompoundBoundingBox.__init__;  sa     	/// /099%OO!~&&&&&r   c                      fd j                                         D             }t          | j         j        t          j         j                   j                  S )Nc                V    i | ]%\  }}||                     j        j                  &S r   )r   rm  r/  )r"   selectorr   r   s      r   r   z,CompoundBoundingBox.copy.<locals>.<dictcomp>M  sA     
 
 
$ dii 2 9::
 
 
r   )rm  rn  re   )	rr  r   r   rg   rq  r   r   rp  rk   )r   rk  s   ` r   r   zCompoundBoundingBox.copyL  sv    
 
 
 
"&"6"<"<">">
 
 

 #K- M$*?@@+
 
 
 	
r   c           	        ddg}| j                                         D ]w\  }}|                                                    d          }|                    d| d|                    d                      |D ]}|                    d|            x|                    d           | j                            | j                                      d          }|                    d	|                    d                      |D ]}|                    d|            |                    d
           d	                    |          S )NzCompoundBoundingBox(z    bounding_boxes={r   r   z = r   z            r   z    selector_args = r   )
rr  r   r   splitr   rd  rm  r:  rg   r   )r   r   r4  r   	bbox_reprpartselector_args_reprs          r   r   zCompoundBoundingBox.__repr__Z  sa   ')?@#399;; 	4 	4OIt--d33ILLDIDD)--2B2BDDEEE! 4 42D2233334W "/;;DKHHNNtTTG,>,B,B1,E,EGGHHH& 	, 	,DLL*D**++++Syyr   rO   c                    | j         S r   rr  r   s    r   rk  z"CompoundBoundingBox.bounding_boxesm  s    ##r   c                    | j         S r   )rq  r   s    r   rm  z!CompoundBoundingBox.selector_argsq  s    ""r   c                    t                               | j        |          | _        t	          j        dt                     d S )NzhOverriding selector_args may cause problems you should re-validate the compound bounding box before use!)rF  r?   rg   rq  r8   r9   r:   r   s     r   rm  z!CompoundBoundingBox.selector_argsu  sB    099$+uMM4	
 	
 	
 	
 	
r   r>   c                @    | j                             | j                  S r   )rq  rB  rg   r   s    r   named_selector_tuplez(CompoundBoundingBox.named_selector_tuple  s    "..t{;;;r   c                    | j         S r   )rp  r   s    r   rn  z#CompoundBoundingBox.create_selector  s    $$r   c                D    t          |           rt          |           S | fS r   )r	   r>   )r[   s    r   _get_selector_keyz%CompoundBoundingBox._get_selector_key  s#    c?? 	::6Mr   c                   |                      |          }| j                            |          st          | d          | j        j        | j        z   }t                              | j        ||| j	                  | j
        |<   d S )Nz is not a selector!r   )r  rm  rY  r.   r/  rc   r
   r?   rg   rk   rr  )r   r[   r   r4  rc   s        r   r   zCompoundBoundingBox.__setitem__  s    **3//	!--i88 	@	>>>???$+dl:*:*C*CKt{ +D +
 +
Y'''r   r   c                D    |                                 D ]
\  }}|| |<   d S r   r   )r   rk  r4  r   s       r   r   zCompoundBoundingBox._validate  s7    '5';';'='= 	+ 	+#I|*DOO	+ 	+r   c                    t          |t                    r0| j        |j        k    o| j        |j        k    o| j        |j        k    S dS r   )r'   r   rk  rm  rn  r   s     r   r   zCompoundBoundingBox.__eq__  sW    e011 	#u';; B&%*==B(E,AA 5r   Fr   r~   r  r   c                    t          |t                    r)||j        }||j        }|j        }|r|j        }|j        }|t          d           | ||||||          S )ab  
        Construct a valid compound bounding box for a model.

        Parameters
        ----------
        model : `~astropy.modeling.Model`
            The model for which this will be a bounding_box
        bounding_box : dict
            Dictionary of possible bounding_box representations
        selector_args : optional
            Description of the selector arguments
        create_selector : optional, callable
            Method for generating new selectors
        order : optional, str
            The order that a tuple representation will be assumed to be
                Default: 'C'
        NzTSelector arguments must be provided (can be passed as part of bounding_box argument))rn  rc   re   )r'   r   rm  rn  re   rc   rk  r.   )	r;   rZ   r   rm  rn  rc   re   r  kwargs	            r   r?   zCompoundBoundingBox.validate  s    : l$788 	7$ , :&"."> &E /&.'6L C  
 s+
 
 
 	
r   c                    || j         v S r   r|  ru   s     r   r   z CompoundBoundingBox.__contains__  s    d***r   c                P    |                      || j                  | |<   | |         S )N)rZ   )rp  rg   rX  s     r   _create_bounding_boxz(CompoundBoundingBox._create_bounding_box  s*    //	/MMYIr   c                    |                      |          }|| v r| j        |         S | j        |                     |          S t	          d| d          )Nz)No bounding box is defined for selector: r6   )r  rr  rp  r  r   )r   r[   r4  s      r   r   zCompoundBoundingBox.__getitem__  se    **3//	'	22".,,Y777W9WWWXXXr   r
   c                0     | j         j        | }| |         S r   )rm  r5  r3  s      r   _select_bounding_boxz(CompoundBoundingBox._select_bounding_box  s    3D&3V<	Ir   r   c                X    |                      |          }|                    ||          S )r   )r  r   )r   r   rT   r   s       r   r   z"CompoundBoundingBox.prepare_inputs  s-    * 0088**;???r   c                   | j                             | j        |          }i }| j                                        D ]\  }}||         |k    rt          |          }|                    |           |                    |          r |                    | j        ||id          }n|	                                }||t          |          <   t          |          dk    rt          d| d| d          |S )NTr  r   zAttempting to fix input z5, but there are no bounding boxes for argument value r6   )rm  rb  rg   rr  r   r~   rd  r   r   r   r>   r-   r.   )	r   r1  r   rb  matchingselector_keyr   new_selector_keynew_bboxs	            r   _matching_bounding_boxesz,CompoundBoundingBox._matching_bounding_boxes
  s$   +::4;QQ"&"6"<"<">"> 	= 	=L$N+u44#'#5#5  $$^444$$X.. +#h%6d  /    HH  $yy{{H4</001x==A>8 > >5:> > >  
 r   c                    |                      ||          }t          | j                  dk    r|d         S t          || j        | j                            | j        |                    S )Nr   r   )r  r-   rm  r   rg   re  )r   r1  r   matching_bounding_boxess       r   _fix_input_selector_argz+CompoundBoundingBox._fix_input_selector_arg#  sk    "&"?"?%"P"Pt!""a''*2..&'"))$+x@@  r   c                    i }| j                                         D ]'\  }}|                    | j        ||id          ||<   (t	          || j        | j                            | j        |                    S )NTr  )rr  r   r   rg   r   rm  rg  )r   r1  r   rk  r  r   s         r   _fix_input_bbox_argz'CompoundBoundingBox._fix_input_bbox_arg/  s    "&"6"<"<">"> 	 	L$+/??h.d ,; , ,N<(( #K))$+x@@
 
 	
r   r   c                V   t          |                                          }|                                }||         }| j                            | j        |          r|                     ||          }n|                     ||          }t          |          dk    r-|	                                }||= |
                    ||          }t          |t                    r
|j        }|}	nt          |t                    r	d}|j        }	|j                            ||	|j        |          S )r   r   N)re   rm  )r~   r  rd  rm  r@  rg   r  r  r-   r   r   r'   r   r  r
   r   r   r?   re   )
r   rZ   r   fixed_input_keysr1  r   r   new_fixed_inputsrm  	bbox_dicts
             r   r   zCompoundBoundingBox.fix_inputs<  s0      1 1 3 344#''))X&))$+x@@ 	=//%@@DD++He<<D  1$$+0022 *??5*:;;Dd/00 	- 5MII.// 	- M,I~&&9DJm ' 
 
 	
r   )NNrb   )
rk  rl  rm  rF  rn  r   rc   rd   re   rS   )rO   rl  )rO   rF  )rO   r>   )rk  r   )NNNrb   F)r   r   rc   r~   re   rS   r  r   )rO   r
   r   r   )rI   rJ   rK   rL   rl   r   r   r   rk  rm  setterr  rn  rM   r  r   r   r   rN   r?   r   r  r   r  r   r  r  r  r   r(  r)  s   @r   r   r     s6        @ %)!' ' ' ' ' ' '"
 
 
     & $ $ $ X$ # # # X# 
 
 
 < < < X< % % X%   \
 
 
+ + + +   
 !&3
 3
 3
 3
 [3
j+ + +  
Y Y Y   
@ @ @ @0   2
 
 

 
 
#
 #
 #
 #
 #
 #
 #
 #
r   r   r   )!rL   
__future__r   r   r   r8   collectionsr   typingr   r   numpyr(   astropy.unitsr   astropy.utilsr	   __all__r   r   r?   infr   r\   r_   ABCra   r
   r*  r,  r>   rF  r   r   r   r   <module>r     sl    # " " " " " 



   " " " " " "                     " " " " " " $ $ $ $ $ $4
5 
?M::lJ lJ lJ lJ lJ lJ lJ lJ` &&'899    2   
TJ TJ TJ TJ TJcg TJ TJ TJno9 o9 o9 o9 o9 o9 o9 o9d #
#:NKK G/ G/ G/ G/ G/- G/ G/ G/T[O [O [O [O [O [O [O [O|@
 @
 @
 @
 @
/ @
 @
 @
 @
 @
r   