
    e                        d Z ddlm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mZmZ ddlmZmZmZmZmZmZ  G d	 d
          Z G d d          Z G d de          Z G d de          Z G d de          ZdS )z
Supplies MultiDimensionalMapping and NdMapping which are multi-dimensional
map types. The former class only allows indexing whereas the latter
also enables slicing over multiple dimension ranges.
    )cycle)
itemgetterN   )util)	DimensionDimensionedViewableElementasdim)dimension_sortget_ndmapping_labelprocess_ellipsessanitize_identifierunique_iterator
wrap_tuplec                   $    e Zd ZdZd Zd Zd ZdS )
item_checka3  
    Context manager to allow creating NdMapping types without
    performing the usual item_checks, providing significant
    speedups when there are a lot of items. Should only be
    used when both keys and values are guaranteed to be the
    right type, as is the case for many internal operations.
    c                     || _         d S Nenabledselfr   s     8lib/python3.11/site-packages/holoviews/core/ndmapping.py__init__zitem_check.__init__#           c                 J    t           j        | _        | j        t           _        d S r   )MultiDimensionalMapping_check_items_enabledr   r   s    r   	__enter__zitem_check.__enter__&   s    /</3|,,,r   c                 (    | j         t          _        d S r   )r    r   r   r   exc_typeexc_valexc_tbs       r   __exit__zitem_check.__exit__*   s    /3},,,r   N__name__
__module____qualname____doc__r   r"   r(    r   r   r   r      sK           < < <= = = = =r   r   c                   $    e Zd ZdZd Zd Zd ZdS )sorted_contextz
    Context manager to temporarily disable sorting on NdMapping
    types. Retains the current sort order, which can be useful as
    an optimization on NdMapping instances where sort=True but the
    items are already known to have been sorted.
    c                     || _         d S r   r   r   s     r   r   zsorted_context.__init__6   r   r   c                 J    t           j        | _        | j        t           _        d S r   )r   sortr    r   r!   s    r   r"   zsorted_context.__enter__9   s    /4'+|$$$r   c                 (    | j         t          _        d S r   )r    r   r3   r$   s       r   r(   zsorted_context.__exit__=   s    '+}$$$r   Nr)   r.   r   r   r0   r0   .   sK           4 4 45 5 5 5 5r   r0   c                       e Zd ZdZ ej        d d          Z ej         ed          gd          Z	 ej        g dd          Z
 ej        dd          Zd	Zd
ZdZd' fd	Zd Zd(dZd Zd Zd Zd Zd) fd	Zd'dZd*dZd Zd( fd	Zd+dZed             Zed             Zed             Z d Z!d Z"d Z#d Z$d,dZ%d,d Z&d! Z'd" Z(d# Z)d$ Z*d% Z+d& Z, xZ-S )-r   a  
    An MultiDimensionalMapping is a Dimensioned mapping (like a
    dictionary or array) that uses fixed-length multidimensional
    keys. This behaves like a sparse N-dimensional array that does not
    require a dense sampling over the multidimensional space.

    If the underlying value for each (key, value) pair also supports
    indexing (such as a dictionary, array, or list), fully qualified
    (deep) indexing may be used from the top level, with the first N
    dimensions of the index selecting a particular Dimensioned object
    and the remaining dimensions indexing into that object.

    For instance, for a MultiDimensionalMapping with dimensions "Year"
    and "Month" and underlying values that are 2D floating-point
    arrays indexed by (r,c), a 2D array may be indexed with x[2000,3]
    and a single floating-point number may be indexed as
    x[2000,3,1,9].

    In practice, this class is typically only used as an abstract base
    class, because the NdMapping subclass extends it with a range of
    useful slicing methods for selecting subsets of the data. Even so,
    keeping the slicing support separate from the indexing and data
    storage methods helps make both classes easier to understand.
    TdefaultconstantDefault)r   r   )r7   boundsr8   z?
        Whether the items should be sorted in the constructor.)r7   docNFc                     t          |t                    r,t          t          j        |          fi t          |          }|||d<    t                      j        i fi t          |           d| _        d| _        |g }t          |t                    r$| 
                    |d         |d                    d S | j        st          |t                    r|                                }n.t          |t                    r|j                                        }t          d |D                       | _        | j        r|                                  d S d S |$|                     t          |                     d S d S )Nkdimsr   Tr   c              3   T   K   | ]#\  }}t          |t                    r|n|f|fV  $d S r   )
isinstancetuple.0kvs      r   	<genexpr>z3MultiDimensionalMapping.__init__.<locals>.<genexpr>{   sT       ? ?(,1 $.a#7#7AaaaT1E ? ? ? ? ? ?r   )r?   r   dictr   get_param_valuessuperr   	_next_ind_check_key_typer@   	_add_itemr   itemsdatar3   _resortupdate)r   initial_itemsr=   params	__class__s       r   r   z MultiDimensionalMapping.__init__i   s   m%<== 	P$/>>OO$v,,OOF#F7O,,tF||,,,# "-mU++ 	-NN=+]1-=>>>>>" 
	--.. ; - 3 3 5 5M+BCC ; - 2 8 8 : : ? ?0=? ? ? ? ?DIy  &KK]++,,,,, '&r   c                    | j         sdS | j        t          || j                  st          | j        t                    rt          d | j        D                       }n| j        j        }t          |           j        }t          |          j        }t          | d| d| d          t          |          | j        k    s&t          dt          |          | j        fz            dS )z
        Applies optional checks to individual data elements before
        they are inserted ensuring that they are of a certain
        type. Subclassed may implement further element restrictions.
        Nc              3   $   K   | ]}|j         V  d S r   )r*   )rB   dts     r   rE   z6MultiDimensionalMapping._item_check.<locals>.<genexpr>   s$      !G!G""+!G!G!G!G!G!Gr   z does not accept z" type, data elements have to be a .zThe data contains keys of length %d, but the kdims only declare %d dimensions. Ensure that the number of kdims match the length of the keys in your data.)
r   	data_typer?   r@   r*   type	TypeErrorlenndimsKeyError)r   dim_valsrM   rW   slfs        r   _item_checkz#MultiDimensionalMapping._item_check   s      	:F^'
40P0P'$.%00 4!!G!G!G!G!GGG		 N3	t**%C::&Ds 4 4T 4 4'04 4 4 5 5 5X$*,, Q "(mmTZ89 : : : -,r   c                 V   |o| j         }t          |t                    s|f}|                     ||           t	          d | j        D             |          }t          d |D                       }t	          | j        |          }|D ],\  }}|j        r |||j        vrt          | d|d          -|rQ|| j        v rHt          | j        |         t          t          f          r!| j        |                             |           n
|| j        |<   |r|                                  dS dS )z
        Adds item to the data, applying dimension types and ensuring
        key conforms to Dimension type and values.
        c                     g | ]	}|j         
S r.   rX   )rB   kds     r   
<listcomp>z5MultiDimensionalMapping._add_item.<locals>.<listcomp>   s    666R666r   c              3   B   K   | ]\  }}d ||fv r|n
 ||          V  d S r   r.   )rB   trD   s      r   rE   z4MultiDimensionalMapping._add_item.<locals>.<genexpr>   s>      MM41adq!fnn!!A$$MMMMMMr   Nz dimension value z# not in specified dimension values.)r3   r?   r@   r_   zipr=   valuesr\   rM   r   rF   rO   rN   )	r   r]   rM   r3   rO   	dim_types
valid_valsdimvals	            r   rK   z!MultiDimensionalMapping._add_item   sm   
 !	(E** 	# {H4((( 664:666AA	MM9MMMMMX..
" 	? 	?HCz ?co#SZ2G2G#  >  >  >  >  > ? ? ?  	'DI--49X.1H$0OPP .Ih&&t,,,,"&DIh 	LLNNNNN	 	r   c                 v   d}t          | j        |          D ]\  }}|j        ||fz  }t          |t                    r.|j        |j        |j        g}|t	          fd|D              fz  }X|t          u r||fz  }ht          |t                    r|fd|D             fz  }| |          fz  }|S )z
        If a type is specified by the corresponding key dimension,
        this method applies the type to the supplied key.
        r.   Nc                 .    g | ]}| |          nd S r   r.   )rB   elkey_types     r   rd   z;MultiDimensionalMapping._apply_key_type.<locals>.<listcomp>   s9     &9 &9 &9*, 79nhhrlll$ &9 &9 &9r   c                 &    g | ]} |          S r.   r.   )rB   rC   rp   s     r   rd   z;MultiDimensionalMapping._apply_key_type.<locals>.<listcomp>   s!    888qxx{{888r   )
rg   r=   rX   r?   slicestartstopstepEllipsislist)r   keys	typed_keyrk   keysl_valsrp   s         @r   _apply_key_typez'MultiDimensionalMapping._apply_key_type   s   
 	DJ-- 	. 	.HCxHcV#		C'' 	.9ch9e &9 &9 &9 &907&9 &9 &9 : < <		cV#		C&& .8888C888::		hhsmm--		r   c                    t          |t                    s|f}n|dk    rdS |d         t          u r9| j        t	          |          z
  dz   }t          d          f|z  |dd         z   }nEt	          |          | j        k     r-| j        t	          |          z
  }|t          d          f|z  z   }|d| j                 }| j        r|                     |          }t	          |          | j        k    r|dfS ||| j        d         fS )z
        Partitions key into key and deep dimension groups. If only key
        indices are supplied, the data is indexed with an empty tuple.
        Keys with indices than there are dimensions will be padded.
        r.   )r.   r.   r   r   N)r?   r@   rv   r[   rZ   rr   rJ   r|   )r   rz   num_pad	map_slices       r   _split_indexz$MultiDimensionalMapping._split_index   s    #u%% 	&CCBYY6q6Xj3s88+a/G;;.7*SW4CCXX
""j3s88+Gt00C$	 	8,,Y77Is88tz!!b= c$*++...r   c                     | j         rt          |t                    r
|r||         S t          |          dk    r| j                            d           |S )z
        Returns slice of data element if the item is deep
        indexable. Warns if attempting to slice an object that has not
        been declared deep indexable.
        r   z;Cannot index into data element, extra data indices ignored.)_deep_indexabler?   r   rZ   paramwarning)r   rM   indicess      r   
_dataslicez"MultiDimensionalMapping._dataslice   sf      	4Jt[$A$A 	4g 	4= \\AJ  3 4 4 4r   c           
          t          t          | j        | j        | j        t          | j                                      | _        d S r   )rF   r   rM   r=   vdimsranger[   r!   s    r   rN   zMultiDimensionalMapping._resort   s@    	4:tz/4TZ/@/@B B C C			r   c                     t          | o| j                  5   t                      j        ||g|R i |cddd           S # 1 swxY w Y   dS )g  Clones the object, overriding data and parameters.

        Args:
            data: New data replacing the existing data
            shared_data (bool, optional): Whether to use existing data
            new_type (optional): Type to cast object to
            link (bool, optional): Whether clone should be linked
                Determines whether Streams and Links attached to
                original object will be inherited.
            *args: Additional arguments to pass to constructor
            **overrides: New keyword arguments to pass to constructor

        Returns:
            Cloned object
        N)r   r   rH   clone)r   rM   shared_dataargs	overridesrR   s        r   r   zMultiDimensionalMapping.clone  s      K=D,=>> 	H 	H 577={GTGGGYGG	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	Hs   AAAc                      j         dk    r j                            d            S t          |t                    s|g}|r|nt                     }|r|nt                     } fd|D             }t          d          5  |                    d j                  }t          j
         |||fd|i|cddd           S # 1 swxY w Y   dS )a  Groups object by one or more dimensions

        Applies groupby operation over the specified dimensions
        returning an object of type container_type (expected to be
        dictionary-like) containing the groups.

        Args:
            dimensions: Dimension(s) to group by
            container_type: Type to cast group container to
            group_type: Type to cast each group to
            dynamic: Whether to return a DynamicMap
            **kwargs: Keyword arguments to pass to each group

        Returns:
            Returns object of supplied container_type containing the
            groups. If dynamic=True returns a DynamicMap instead.
        r   z)Cannot split Map with only one dimension.c                 >    g | ]}                     |d           S )Tstrictget_dimensionrB   dr   s     r   rd   z3MultiDimensionalMapping.groupby.<locals>.<listcomp>.  s,    MMMQd((4(88MMMr   Fr3   N)r[   r   r   r?   rw   rX   r   popr3   r   ndmapping_groupby)r   
dimensionscontainer_type
group_typekwargsr3   s   `     r   groupbyzMultiDimensionalMapping.groupby  sT   $ :??JJKKKKJ-- 	&$J+9ItDzz#-=ZZ4::
MMMM*MMM
 	K 	K::fdi00D)$
N*4K K;?KCIK K	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	Ks   2CC
Cc           	         t          |          }||                                 v rt          |j         d          |r| j        rt          d          |r@| j        dd         }|                    ||           t          |          }|| j        z  }n5| j	        dd         }|                    ||           t          |          }t          |t                    st          |d          st          |g          }n/t          |          t          |           k    st          d          i }t!          || j                                                  D ]y\  }	\  }
}|r8t'          |          }|                    ||	           t)          |          ||
<   Bt'          |
          }|                    ||	           ||t)          |          <   z | j        |fi t          |fi |S )a  Adds a dimension and its values to the object

        Requires the dimension name or object, the desired position in
        the key dimensions and a key value scalar or sequence of the
        same length as the existing keys.

        Args:
            dimension: Dimension or dimension spec to add
            dim_pos (int) Integer index to insert dimension at
            dim_val (scalar or ndarray): Dimension value(s) to add
            vdim: Disabled, this type does not have value dimensions
            **kwargs: Keyword arguments passed to the cloned element

        Returns:
            Cloned object containing the new dimension
        z dimension already definedz;Cannot add value dimension to object that is deep indexableN)r   r=   __iter__z;Added dimension values must be same lengthas existing keys.)r
   r   	Exceptionnamer   r   insertrF   r[   r=   r?   strhasattrr   rZ   
ValueErrorrg   rM   rL   rw   r@   r   )r   	dimensiondim_posdim_valvdimr   dimsr   rL   dvalrz   rl   new_valnew_keys                 r   add_dimensionz%MultiDimensionalMapping.add_dimension5  s	   " )$$	))))y~IIIJJJ 	[D( 	[YZZZ 	*:aaa=DKK+++D)))Jtz!GG:aaa=DKK+++D)))Jgs## 	577J+G+G 	5WI&&GGWT** 4 5 5 5  #GTY__->-> ? ? 	, 	,D*3 ,s))w---"7^^c

s))w---(+eGnn%%tz%>>4
#=#=f#=#=>>>r   c                     t          j                  rgnfd j        D             } fd|D             }t          |                      fd j                                        D             |          S )zDrops dimension(s) from keys

        Args:
            dimensions: Dimension(s) to drop

        Returns:
            Clone of object with with dropped dimension(s)
        c                     g | ]}|v|	S r.   r.   )rB   r   r   s     r   rd   z:MultiDimensionalMapping.drop_dimension.<locals>.<listcomp>v  s#    ===a*)<)<)<)<)<r   c                 :    g | ]}                     |          S r.   get_dimension_indexr   s     r   rd   z:MultiDimensionalMapping.drop_dimension.<locals>.<listcomp>w  s'    >>>AD,,Q//>>>r   c                 0    g | ]\  }} |          |fS r.   r.   )rB   rC   rD   
key_getters      r   rd   z:MultiDimensionalMapping.drop_dimension.<locals>.<listcomp>y  s*    LLL$!QJJqMM1-LLLr   r   )npisscalarr=   r   r   rM   rL   )r   r   r   dim_indsr   s   ``  @r   drop_dimensionz&MultiDimensionalMapping.drop_dimensionl  s     &([%<%<Lj\\*
====4:===>>>>>>>*
zzLLLL$)//:K:KLLL $  & & 	&r   c                                           d           j        v r8t          j         fd j                                        D                       S                                  v r<fd D             }t          j        |          }r|nt          j	        |          S t                                                    S )a  Return the values along the requested dimension.

        Args:
            dimension: The dimension to return values for
            expanded (bool, optional): Whether to expand values
                Whether to return the expanded values, behavior depends
                on the type of data:
                  * Columnar: If false returns unique values
                  * Geometry: If false returns scalar values per geometry
                  * Gridded: If false returns 1D coordinates
            flat (bool, optional): Whether to flatten array

        Returns:
            NumPy array of values along the requested dimension
        Tr   c                 F    g | ]}|                                        S r.   r   )rB   rC   r   r   s     r   rd   z<MultiDimensionalMapping.dimension_values.<locals>.<listcomp>  s,    ^^^Qt77	BBC^^^r   c                 j    g | ]/}|                                 v |                              0S r.   )r   dimension_values)rB   ro   r   expandedflats     r   rd   z<MultiDimensionalMapping.dimension_values.<locals>.<listcomp>  sG     7 7 7"bmmoo55 )))XtDD555r   )r   r=   r   arrayrM   rx   r   concatenater   unique_arrayrH   r   )r   r   r   r   rh   valsrR   s   ````  r   r   z(MultiDimensionalMapping.dimension_values}  s      &&y&>>	
""8^^^^^TY^^M]M]^^^___))))7 7 7 7 7 7t 7 7 7F>&))D#@44):4)@)@@77++IxFFFr   c                 F   	 |g }d  j         D             }t          |t                    s|g}nt          |          s fd|D             } fd|D             fd j                                        D             }t          d t          | j                                                  D                       }d  j         D             	                    |          		 fd|D             }t          t          |                    t          |          k    r|st          d	          t          |          r fd
	D             }ni }t          t                    k              5                       |||          cddd           S # 1 swxY w Y   dS )a  Reindexes object dropping static or supplied kdims

        Creates a new object with a reordered or reduced set of key
        dimensions. By default drops all non-varying key dimensions.

        Reducing the number of key dimensions will discard information
        from the keys. All data values are accessible in the newly
        created object as the new labels must be sufficient to address
        each value uniquely.

        Args:
            kdims (optional): New list of key dimensions after reindexing
            force (bool, optional): Whether to drop non-unique items

        Returns:
            Reindexed object
        Nc                     g | ]	}|j         
S r.   r   rB   r   s     r   rd   z3MultiDimensionalMapping.reindex.<locals>.<listcomp>  s    000QV000r   c           	      z    g | ]7}t          t                              |                              d k    5|8S )r   )rZ   setr   r   s     r   rd   z3MultiDimensionalMapping.reindex.<locals>.<listcomp>  sN     E E E1D$9$9!$<$< = =>>!CC CCCr   c                 :    g | ]}                     |          S r.   r   )rB   ro   r   s     r   rd   z3MultiDimensionalMapping.reindex.<locals>.<listcomp>  s'    @@@B4++B//@@@r   c                 H    g | ]t          fd D                       S )c              3   (   K   | ]}|         V  d S r   r.   )rB   irC   s     r   rE   z=MultiDimensionalMapping.reindex.<locals>.<listcomp>.<genexpr>  s'      ,,qad,,,,,,r   )r@   )rB   rC   r   s    @r   rd   z3MultiDimensionalMapping.reindex.<locals>.<listcomp>  s7    GGG,,,,G,,,,,GGGr   c              3   $   K   | ]\  }}||fV  d S r   r.   rA   s      r   rE   z2MultiDimensionalMapping.reindex.<locals>.<genexpr>  sC       @ @1QF@ @ @ @ @ @r   c                     h | ]	}|j         
S r.   r   r   s     r   	<setcomp>z2MultiDimensionalMapping.reindex.<locals>.<setcomp>  s    3331333r   c                 B    g | ]}|v                     |          S r.   r   )rB   r   reduced_dimsr   s     r   rd   z3MultiDimensionalMapping.reindex.<locals>.<listcomp>  s;     0 0 0,.. ((++...r   zCGiven dimension labels not sufficientto address all values uniquelyc                 n    i | ]1}                     |                              |          d          2S r   )r   r   r   s     r   
<dictcomp>z3MultiDimensionalMapping.reindex.<locals>.<dictcomp>  s<    ^^^AT''**D,A,A!,D,DQ,G^^^r   )r=   cdims)r=   r?   rw   rZ   rM   rx   rF   rg   rh   
differencer   r   r   sortedr   )
r   r=   force	old_kdimsrx   reindexed_itemsr   r   r   r   s
   `       @@r   reindexzMultiDimensionalMapping.reindex  s\   $ =E00TZ000	%&& 	EGEEU 	EE E E E	 E E EE@@@@%@@@GGGGdinn6F6FGGG @ @!$T49+;+;+=+=!>!>@ @ @ @ @33
333>>uEE0 0 0 0 0U 0 0 0
 s4yy>>SYY&&u& = > > > t99 	^^^^Q]^^^EEE6'??233 	+ 	+::oZ$)  + +	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+s   1FFFc                 |    t          |           r,t          | j                                                  d         ndS )z<Returns the item highest data item along the map dimensions.N)rZ   rw   rM   rh   r!   s    r   lastzMultiDimensionalMapping.last  s5     034yyBtDI$$&&''++dBr   c                 r    t          |           r't          |                                           d         ndS )zReturns the last key value.r   N)rZ   rw   rx   r!   s    r   last_keyz MultiDimensionalMapping.last_key  s/     ),D		;tDIIKK  $$t;r   c           
      "   t          |                                           dk    r^| j        j        dt          |                                           t          |                                 d                   j        fz  z   }n| j        j        dz   }|dt          |          dz
  z  dz   z  }d | j                                        D             }| j        D ]}t          | |          }|r;||         
                    d          d         }||                                 d	z  }|D ]d}|                     |j                  \  }}|j        r*|                    |          |                    |          }}|d
|j         d| d| dz  }e|S )z
        Prints information about the Dimensioned object, including the
        number and type of objects contained within it and information
        about its dimensions.
        r   z  containing %d items of type %s
z containing no items
-r   z

c                     i | ]\  }}||	S r.   r.   rA   s      r   r   z0MultiDimensionalMapping.info.<locals>.<dictcomp>  s    >>>DAq1a>>>r   _z Dimensions: 
z	 z: z...z 
)rZ   rh   rR   r*   rx   rX   _dim_aliasesrL   _dim_groupsgetattrsplit
capitalizer   r   value_formatpprint_label)r   info_straliasesgroupr   r   dmindmaxs           r   infozMultiDimensionalMapping.info  s    ""~.:c$))++>N>N>B4;;==QRCS>T>T>]>_ __HH ~.1IIHSCMM!O,66>>D$5$;$;$=$=>>>% 		G 		GE u--J C,,S11!4u//11BBBB G G!ZZ//
d> L!"!5!5q~~d7K7K$DF!.FFDFFTFFFF	G
 r   c                     t          |t                    rX fd|j        D             }t          |          |j        k    rt          d          |r|                    |          }|j        }|                                D ]\  }} 	                    ||d            j
        r                                  dS dS )zMerges other item with this object

        Args:
            other: Object containing items to merge into this object
                Must be a dictionary or NdMapping type
        c                 &    g | ]}|j         v|S r.   r   r   s     r   rd   z2MultiDimensionalMapping.update.<locals>.<listcomp>  s%    BBB!atz.A.AA.A.A.Ar   zHCannot update with NdMapping that has a different set of key dimensions.F)r3   N)r?   	NdMappingr=   rZ   r[   r\   r   rM   rL   rK   r3   rN   )r   otherr   rz   rM   s   `    r   rO   zMultiDimensionalMapping.update  s     eY'' 	BBBBu{BBBD4yyEK''  E F F F 3,,T22JE 	2 	2ICNN35N11119 	LLNNNNN	 	r   c                     | j         dk    r#d | j                                        D             S t          | j                                                  S )z& Returns the keys of all the elements.r   c                     g | ]
}|d          S r   r.   )rB   rC   s     r   rd   z0MultiDimensionalMapping.keys.<locals>.<listcomp>	  s    333QAaD333r   )r[   rM   rx   rw   r!   s    r   rx   zMultiDimensionalMapping.keys  sG    :??33$).."2"23333	(()))r   c                 N    t          | j                                                  S )z'Returns the values of all the elements.)rw   rM   rh   r!   s    r   rh   zMultiDimensionalMapping.values  s    DI$$&&'''r   c           	          t          t          t          |                                           t          |                                                               S )z5Returns all elements as a list in (key,value) format.)rw   rg   rx   rh   r!   s    r   rL   zMultiDimensionalMapping.items  s:    CTYY[[))4+>+>??@@@r   c                 @    	 |dS | |         S # t           $ r |cY S w xY w)z,Standard get semantics for all mapping typesN)r\   r   rz   r7   s      r   getzMultiDimensionalMapping.get  s?    	{t9 	 	 	NNN	s     c                 h    t          |t                    s|f}| j                            ||          S )z,Standard pop semantics for all mapping types)r?   r@   rM   r   r   s      r   r   zMultiDimensionalMapping.pop"  s.    #u%%3cVsy}}S'***r   c                     |t           dfv r| S |                     |          \  }}|                     | j        |         |          S )z
        Allows multi-dimensional indexing in the order of the
        specified key dimensions, passing any additional indices to
        the data elements.
        r.   )rv   r   r   rM   )r   rz   r   
data_slices       r   __getitem__z#MultiDimensionalMapping.__getitem__(  sK     8R.  K $ 1 1# 6 6	:ty3Z@@@r   c                 6    |                      ||d           dS )zAdds item to mappingF)rO   N)rK   )r   rz   values      r   __setitem__z#MultiDimensionalMapping.__setitem__4  s     sE%00000r   c                      t          |           S r   )reprr!   s    r   __str__zMultiDimensionalMapping.__str__9  s    Dzzr   c                 D    t          |                                           S )zIterates over mapping values)iterrh   r!   s    r   r   z MultiDimensionalMapping.__iter__=  s    DKKMM"""r   c                 z    | j         dk    r|| j                                        v S ||                                 v S )Nr   )r[   rM   rx   )r   rz   s     r   __contains__z$MultiDimensionalMapping.__contains__B  s7    :??$)..****$))++%%r   c                 *    t          | j                  S r   )rZ   rM   r!   s    r   __len__zMultiDimensionalMapping.__len__H  s    49~~r   )NN)TTNTFNFr   ).r*   r+   r,   r-   r   Stringr   Listr   r=   r   Booleanr3   rW   r   r   r   r_   rK   r|   r   r   rN   r   r   r   r   r   r   propertyr   r   r   rO   rx   rh   rL   r   r   r  r  r	  r   r  r  __classcell__rR   s   @r   r   r   B   s        2 EL!:TJJJEEJ		) 4 45EEEEEJr&4@@@E5= ,B C C CD IOL- - - - - -4: : :2   @  ./ / /6  C C C
H H H H H H(K K K K@4? 4? 4? 4?n& & &"G G G G G G8-+ -+ -+ -+` C C XC
 < < X<
   X6  ** * *( ( (
A A A
   + + + +	A 	A 	A1 1 1
  # # #
& & &      r   r   c                   r    e Zd ZdZ ej        d d          Zd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd ZdS )r   av  
    NdMapping supports the same indexing semantics as
    MultiDimensionalMapping but also supports slicing semantics.

    Slicing semantics on an NdMapping is dependent on the ordering
    semantics of the keys. As MultiDimensionalMapping sort the keys, a
    slice on an NdMapping is effectively a way of filtering out the
    keys that are outside the slice range.
    Tr6   c                    t          |t          j                  r|j        j        dk    rut          |          t          |           k    st          d          t          || j        	                                          }| 
                    d |D                       S t          |t                    r|dk    r| j        s| j        d         S t          |t                    r|dk    s	|t          u r| S t          d t          |          D                       rt!          | |          }|                     |          \  }}|                     |          }|                     |          }t)          d |D                       r!|                     | j        |         |          S |                     |          }| j        	                                }t/          t          || j                            D ]\  \  }|j        fd|D             } g }|D ]I\  }	}
|                     |
|          }|st          |t                    r|                    |	|f           Jt          |          dk    rt5          d	          t7          d
          5  | 
                    |          cddd           S # 1 swxY w Y   dS )z
        Allows slicing operations along the key and data
        dimensions. If no data slice is supplied it will return all
        data elements, otherwise it will return the requested slice of
        the data.
        bz0Boolean index must match length of sliced objectc                     g | ]	\  }}||
S r.   r.   )rB   citems      r   rd   z)NdMapping.__getitem__.<locals>.<listcomp>d  s!    BBB4BtBBBr   r.   c              3   (   K   | ]}t           |u V  d S r   )rv   )rB   sls     r   rE   z(NdMapping.__getitem__.<locals>.<genexpr>i  s&      AABRAAAAAAr   c              3      K   | ]<}t          |t          t          t          t          f          pt          |           V  =d S r   )r?   rr   r   rw   r@   callable)rB   ro   s     r   rE   z(NdMapping.__getitem__.<locals>.<genexpr>p  sW       $ $ rE3e#<==M"N $ $ $ $ $ $r   c                 z    g | ]7\  }} r                     |                   n|                   3||f8S r.   )index)rB   rC   rD   cidx	conditionrh   s      r   rd   z)NdMapping.__getitem__.<locals>.<listcomp>x  se     ? ? ?DAq%I)/'=fll1T7&;&;&;56tW> >?!Q ? ? ?r   r   z No items within specified slice.FN)r?   r   ndarraydtypekindrZ   
IndexErrorrg   rM   rL   r   r@   r=   rv   anyr   r   r   _transform_indices_expand_sliceallr   _generate_conditions	enumeraterh   appendr\   r   )r   
indexslice	selectionr   r  
conditionsrL   rk   sliced_itemsrC   rD   	val_slicer%  r&  rh   s               @@@r   r  zNdMapping.__getitem__Y  s2    j"*-- 
	<*2B2G32N2Nz??c$ii// !STTTJ	(9(9::I::BB9BBBCCC
E** 	<zR/?/?
/?9R= U++ 	<
b0@0@ZS[E[E[KAA*Z*@*@AAAAA 	<)$
;;J $ 1 1* = =	:++I66	&&y11	 $ $"$ $ $ $ $ 	0??49Y#7DDD229==JIOO%%E*3C
DJ4O4O*P*P ? ?&&y#? ? ? ? ? ?E ? ? ? L 8 81 OOAz::	 8
9e < < 8 ''I777<  A%%ABBBE"" 0 0zz,//0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0s   J;;J?J?c                    t          | j                                                  }g }t          |          D ].\  }t	          |t
                    r|j        t          |j        |j                  }|t          d          k    r| 	                                nO|j        | 
                    |          n2|j        |                     |          n|                     |          t          fd|D                       }|                    t          fd|D             ddt!          |j                                                |                    |           0t#          |          S )z>
        Expands slices containing steps into a list.
        Nc              3   (   K   | ]}|         V  d S r   r.   )rB   rC   idxs     r   rE   z*NdMapping._expand_slice.<locals>.<genexpr>  s'      *@*@a1S6*@*@*@*@*@*@r   c                 *    g | ]} |          |S r.   r.   )rB   rC   r&  s     r   rd   z+NdMapping._expand_slice.<locals>.<listcomp>  s&    $I$I$I1IIaLL$IQ$I$I$Ir   )rw   rM   rx   r0  r?   rr   ru   rs   rt   _all_condition_upto_condition_from_condition_range_conditionr   r1  r   intr@   )	r   r   rx   r   inddim_indr]   r&  r9  s	          @@r   r-  zNdMapping._expand_slice  sf    DINN$$%%!'** 	% 	%HC#u%% %#(*>	3844eDkk)) $ 3 3 5 5II]* $ 4 4W = =II\) $ 4 4W = =II $ 5 5g > >I**@*@*@*@4*@*@*@@@$I$I$I$I$I$I$I//CPSPXMM/$Z [ [\\\\$$$$Xr   c                     |S )z
        Identity function here but subclasses can implement transforms
        of the dimension indices from one coordinate system to another.
        r.   )r   r   s     r   r,  zNdMapping._transform_indices  s	    
 r   c                    g }t          | j        |          D ]R\  }t          |t                    r|j        |j        }}j        rEj        }t          |dn|                    |          |dn|                    |                    }|t          d          k    r(|                    | 	                                           |)|                    | 
                    |                     |*|                    |                     |                     |                    |                     |                     2t          |t          t          f          r?j        rfd|D             }|                    |                     |                     |t           u r)|                    | 	                                           t#          |          r|                    |           t          |t$                    rt'          d          j        rj                            |          }|                    |                     |                     T|S )zR
        Generates filter conditions used for slicing the data structure.
        Nc                 D    g | ]}j                             |          S r.   )rh   r$  )rB   r   rk   s     r   rd   z2NdMapping._generate_conditions.<locals>.<listcomp>  s9     !; !; !;%, "%!1!1'!:!: !; !; !;r   z9Keys may only be selected with sets or lists, not tuples.)rg   r=   r?   rr   rs   rt   rh   r$  r1  r;  r<  r=  r>  r   rw   _values_conditionrv   r"  r@   r*  _value_condition)r   r   r4  	dim_slicers   rt   rh   rk   s          @r   r/  zNdMapping._generate_conditions  sx    
!$*i88 	D 	DNC)U++ D'oy~t: T ZF %emddeATAT.2lddT@R@R!T !TId++%%d&9&9&;&;<<<<]%%d&:&:9&E&EFFFF\%%d&:&:9&E&EFFFF%%d&;&;I&F&FGGGGIT{33 D: ;!; !; !; !;09!; !; !;I!!$"8"8"C"CDDDDh&&!!$"5"5"7"78888)$$ D!!),,,,I// D !\]]]: < #
 0 0 ; ;I!!$"7"7	"B"BCCCCr   c                     fdS )Nc                     | k    S r   r.   )xr  s    r   <lambda>z,NdMapping._value_condition.<locals>.<lambda>  s    e r   r.   )r   r  s    `r   rF  zNdMapping._value_condition  s    #####r   c                     fdS )Nc                     | v S r   r.   )rJ  rh   s    r   rK  z-NdMapping._values_condition.<locals>.<lambda>  s    f r   r.   )r   rh   s    `r   rE  zNdMapping._values_condition  s    $$$$$r   c                 ,    j         fd}nfd}|S )Nc                 8    j         | cxk    o
j        k     nc S r   )rs   rt   rJ  rr   s    r   rK  z,NdMapping._range_condition.<locals>.<lambda>  s'    U[A::::
:::: r   c                 ^    j         | cxk    o
j        k     nc o| j         z
  j        z   S r   )rs   rt   ru   rP  s    r   rK  z,NdMapping._range_condition.<locals>.<lambda>  sB    U[A::::
:::: .5;%*,@. r   ru   r   rr   lmbds    ` r   r>  zNdMapping._range_condition  s6    :::::DD. . . .Dr   c                 ,    j         fd}nfd}|S )Nc                     | j         k     S r   )rt   rP  s    r   rK  z+NdMapping._upto_condition.<locals>.<lambda>  s    Q^ r   c                 0    | j         k     o
| j        z   S r   )rt   ru   rP  s    r   rK  z+NdMapping._upto_condition.<locals>.<lambda>  s    Q^DQ^0D r   rR  rS  s    ` r   r<  zNdMapping._upto_condition  s.    :++++DDDDDDDr   c                 ,    j         fd}nfd}|S )Nc                     | j         k    S r   )rs   rP  s    r   rK  z+NdMapping._from_condition.<locals>.<lambda>  s    Q%+- r   c                 >    | j         k    o| j         z
  j        z  S r   )rs   ru   rP  s    r   rK  z+NdMapping._from_condition.<locals>.<lambda>  s     Q%+-PAekMUZ3O r   rR  rS  s    ` r   r=  zNdMapping._from_condition  s.    :----DDPPPPDr   c                     d S )Nc                     dS r  r.   )rJ  s    r   rK  z*NdMapping._all_condition.<locals>.<lambda>  s     r   r.   r!   s    r   r;  zNdMapping._all_condition  s
    ~r   N)r*   r+   r,   r-   r   r  r   r  r-  r,  r/  rF  rE  r>  r<  r=  r;  r.   r   r   r   r   L  s          ELt<<<E*0 *0 *0Z  0  # # #L$ $ $% % %          r   r   c                        e Zd ZdZeefZdZdZdZ	d fd	Z
ddZddZddZed	             Zej        d
             Zed             Zej        d             Zed             Zed             Z fdZddZd Z xZS )UniformNdMappinga  
    A UniformNdMapping is a map of Dimensioned objects and is itself
    indexed over a number of specified dimensions. The dimension may
    be a spatial dimension (i.e., a ZStack), time (specifying a frame
    sequence) or any other combination of Dimensions.

    UniformNdMapping objects can be sliced, sampled, reduced, overlaid
    and split along its and its containing Element's dimensions.
    Subclasses should implement the appropriate slicing, sampling and
    reduction methods for their Dimensioned type.
    TFNc                     d | _         d |c| _        | _        d |c| _        | _         t                      j        |fd|i| d S )Nr=   )_type_group_checkr   _label_checklabelrH   r   )r   rP   r=   r   rc  rQ   rR   s         r   r   zUniformNdMapping.__init__  sV    
(,e%4:(,e%4:>>e>v>>>>>r   c                 $  	
 | j                                         }|                    dd          | j        k    r|                    d           |                    dd          | j        k    r|                    d           || j        }n;|}|j                                         		fd|                                D             }t          |fi |}d|vr|t          |           dfv r
| j        |d<   ||r| j        }|r
| j        |d<   t          | dt          |           j        z   dz   g           
t!          | o| j                  5   ||g|R i 
fd	|                                D             cddd           S # 1 swxY w Y   dS )
r   r   Nrc  c                 $    i | ]\  }}|v 	||S r.   r.   )rB   rC   rD   
new_paramss      r   r   z*UniformNdMapping.clone.<locals>.<dictcomp>$  s/     * * *Aj 1(r   idplot_idr   __pos_paramsc                 $    i | ]\  }}|v	||S r.   r.   )rB   rC   rD   pos_argss      r   r   z*UniformNdMapping.clone.<locals>.<dictcomp>1  s6     .D .D .Dca12(1B1B /01B1B1Br   )r   rh   r   _groupr   _labelrR   objectsrL   rF   rX   rg  rM   _plot_idr   r*   r   r   )r   rM   r   new_typelinkr   r   settings
clone_typerf  rk  s            @@r   r   zUniformNdMapping.clone	  sF   " :$$&&<<&&$+55LL!!!<<&&$+55LL!!!JJ!J!//11J* * * *)9)9 * * *H..I..xHdT0B$B$B!WHTN<K<9D 4&*m#4tDzz':!:^!KRPPK=D,=>> 	E 	E:d ET E E E .D .D .D .DX^^=M=M .D .D .D E E	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	Es   *FF	F	c           
          ddl m} ddlm} s j        t          t                    sg j        dk    r?t                     j        k    r' 	                    fd j        D                       }n?t           fdD                       rt          d fgdg          }nt          d          |                    d	
          }|                                D ]i\  }	}
|
                                d         }t          |t                    r@t!          d |
                                D                       }|
                    |          }
t#          |
                                d         d          r= ||
          }r/ |j        |
j        j        fi }|
                    |          }nt+          |
j        |          rft#           d          rV                                 \  }}|
                    t!          fdt/          ||          D                                 }nt1          d          |||	<   k j        t                    z
  r|n|j        S )a  Concatenates and aggregates along supplied dimensions

        Useful to collapse stacks of objects into a single object,
        e.g. to average a stack of Images or Curves.

        Args:
            dimensions: Dimension(s) to collapse
                Defaults to all key dimensions
            function: Aggregation function to apply, e.g. numpy.mean
            spreadfn: Secondary reduction to compute value spread
                Useful for computing a confidence interval, spread, or
                standard deviation.
            **kwargs: Keyword arguments passed to the aggregation function

        Returns:
            Returns the collapsed element or HoloMap of collapsed
            elements
        r   )concat)CompositeOverlayc                     g | ]}|v|	S r.   r.   )rB   rk   r   s     r   rd   z-UniformNdMapping.collapse.<locals>.<listcomp>O  s-     #= #= #=3&)&;&; $'&;&;&;r   c              3   *   K   | ]}|j         v V  d S r   r   r   s     r   rE   z,UniformNdMapping.collapse.<locals>.<genexpr>R  s)      55Qdj555555r   r   tmpzSupplied dimensions not found.F)r   r   c                 @    g | ]\  }}||                                 fS r.   collapserA   s      r   rd   z-UniformNdMapping.collapse.<locals>.<listcomp>[  s6     # # #*.!QQ

%# # #r   	interface_split_overlaysc           	      :    g | ]\  }}| |j         dd fS ))functionspreadfnr.   r{  )rB   rz   ndmapr  r   r  s      r   rd   z-UniformNdMapping.collapse.<locals>.<listcomp>f  sL     . . ."U .%.X(XXXQWXXY. . .r   zQCould not determine correct collapse operation for items of type: {group.type!r}.)rM   ru  overlayrv  r=   r?   rw   r[   rZ   r   r.  r^  r\   r   rL   rh   rF   r   	aggregater   rX   
issubclassr~  rg   r   )r   r   r  r  r   ru  rv  groups	collapsedrz   r   r   
group_dataaggrx   mapss   `````           r   r|  zUniformNdMapping.collapse5  s   & 	!     ------ 	$J*d++F:,Z:>>c*oo;;\\ #= #= #= #=$* #= #= #= > >FF 5555*55555 	=%4ykE7;;FF;<<<LLUL33	 ,,.. 	( 	(JC<<>>"%D$ 011 0! # #27++--# # #  
 J//u||~~b);77 #VE]]
 1.*.uz/?8^^W]^^C!&CJEJ(899 
gdL]>^>^ 
!1133
d"ZZ . . . . . .&)$oo. . . ) )  


 !9   (IcNN Js:6JyyINJr   c                     |
 j         d}n fd|D             fd|D             } fdD             }g } j                                        D ]\  }|                    ||          }d D             }fd|D             }	|rwt	          |          fd|	D             }
|j        j        dgk    r'|
|j        gz  }
|t          |j        j                  z  }|                    |
          }||j        _        n:|	D ]7\  }}d}||v r|d	|z  z   }||v r|dz  }||v |	                    d
||           8|
                    |           t          j        |          S )a  Convert dimension values to DataFrame.

        Returns a pandas dataframe of columns along each dimension,
        either completely flat or indexed by key dimensions.

        Args:
            dimensions: Dimensions to return as columns
            multi_index: Convert key dimensions to (multi-)index

        Returns:
            DataFrame of columns corresponding to each dimension
        Nc                 L    g | ] }|j         v                     |          !S r.   )r=   r   r   s     r   rd   z+UniformNdMapping.dframe.<locals>.<listcomp>  s9      4  4  4!#$
?? !% 2 21 5 5#2??r   c                     g | ]}|v|	S r.   r.   )rB   r   outer_dimensionss     r   rd   z+UniformNdMapping.dframe.<locals>.<listcomp>  s.      >  >  >a#$,<#<#< !"#<#<#<r   c                 >    g | ]}|                     |          fS r.   r   r   s     r   rd   z+UniformNdMapping.dframe.<locals>.<listcomp>  s,    KKKQD,,Q//0KKKr   c                     g | ]	}|j         
S r.   r   r   s     r   rd   z+UniformNdMapping.dframe.<locals>.<listcomp>  s    666QV666r   c                 4    g | ]\  }}|j         |         fS r.   r   )rB   r   r   rz   s      r   rd   z+UniformNdMapping.dframe.<locals>.<listcomp>  s(    :::TQQ(:::r   c                 "    g | ]\  }}|gz  S r.   r.   )rB   r   rD   lengths      r   rd   z+UniformNdMapping.dframe.<locals>.<listcomp>  s#    ;;;$!QA3v:;;;r   r   z_%dr   )r=   rM   rL   dframerZ   r$  namesrw   	set_indexr   r1  pdru  )r   r   multi_indexinner_dimensionsindsdframeselementdfr  key_dimsindexesrk   rl   dimnrz   r  r  s   `             @@@r   r  zUniformNdMapping.dframes  s    #z# 4  4  4  4z  4  4  4 >  >  >  >:  >  >  >KKKK:JKKK IOO-- 	 	LC 0+>>B66%5666E::::T:::H +R;;;;(;;;8>dV++z)GT"(.111E\\'**!& ( + +HCD))!%$,."99 AID )) IIac****NN2y!!!r   c                     | j         r| j         S t          |           rt          | d          nd}|t          |           j        S |S )zGroup inherited from itemsr   N)rl  rZ   r   rX   r*   r   r   s     r   r   zUniformNdMapping.group  sO     ; 	;7:4yyJ$T7333d=::&&r   c                 n    |+t          j        |          st          d| j        z            || _        d S Nz.Supplied group %s contains invalid characters.)r   	allowabler   r   rl  r  s     r   r   zUniformNdMapping.group  E    %8%B5%I%I +-1Z8 9 9 9r   c                 l    | j         r| j         S t          |           rt          | d          }|dn|S dS )zLabel inherited from itemsrc  N )rm  rZ   r   r   rc  s     r   rc  zUniformNdMapping.label  sF     ; 	;YY 	'g66E22E12r   c                 n    |+t          j        |          st          d| j        z            || _        d S r  )r   r  r   r   rm  r  s     r   rc  zUniformNdMapping.label  r  r   c                     | j         3t          |           r$|                                 d         j        | _         | j         S )z+The type of elements stored in the mapping.Nr   )r`  rZ   rh   rR   r!   s    r   rX   zUniformNdMapping.type  s6     :#d))q)3DJzr   c                 ,    |                      d           S r   rb   r!   s    r   empty_elementzUniformNdMapping.empty_element  s    yyr   c                    | j         sd S | j        Vt          |          | j        k    r>t          | j        j         dt          |          j         d| j        j         d          t                                          ||           d S )Nz0 must only contain one type of object, not both z and rV   )r   rX   AssertionErrorrR   r*   rH   r_   )r   r]   rM   rR   s      r   r_   zUniformNdMapping._item_check  s      	^FY"T

di(?(? DN$;  "]  "]mqrvmwmw  nA  "]  "]  HL  HQ  HZ  "]  "]  "]  ^  ^  ^Hd+++++r   c                 "   ddl m} t          t          |                     r| j        j        k    r$t          dt          |           j        z            g }t          | j        	                                          }t          j        	                                          }t          j        ||z             D ]m}| j                            |          }j                            |          }	||	g}
n|	|g}
nr|	|g}
n||	g}
|                    | ||
          f           n|                     |          S fd|                                 D             }	 |                     |          S # t           $ r
 t"          cY S w xY w)Nr   )Overlayz:Can only overlay two %ss with non-matching key dimensions.c                 2    g | ]\  }}|r|z  n|z  fS r.   r.   )rB   rC   ro   r   reverses      r   rd   z,UniformNdMapping.__mul__.<locals>.<listcomp>  sC     6 6 6$q" WDurzz"u*E 6 6 6r   )r  r  r?   rX   r=   r\   r*   rw   rM   rx   r   r   r   r1  r   rL   NotImplementedErrorNotImplemented)r   r   r  r  rL   	self_keys
other_keysrz   self_elother_elr  overlayed_itemss    ``         r   __mul__zUniformNdMapping.__mul__  s   $$$$$$eT$ZZ(( 	%zU[((  >!%d!4 5 6 6 6 ETY^^--..Iejoo//00J+Ij,@AA 3 3)--,, :>>#..?$:DD%#9DD /$g.DD#X.Dc774==12222::e$$$6 6 6 6 6(,

6 6 6	"::o..." 	" 	" 	"!!!!	"s   %E: :FFc                 0    |                      |d          S )NT)r  )r  )r   r   s     r   __rmul__zUniformNdMapping.__rmul__  s    ||E4|000r   )NNNN)NTNT)NNNr  r  )r*   r+   r,   r-   r	   r   rW   _UniformNdMapping__abstractr   _auxiliary_componentr   r   r|  r  r  r   setterrc  rX   r  r_   r  r  r  r  s   @r   r^  r^    s       
 
 !),IJO ? ? ? ? ? ?)E )E )E )EX;K ;K ;K ;K|-" -" -" -"`   X \  \   X \  \   X   X, , , , ," " " "@1 1 1 1 1 1 1r   r^  )r-   	itertoolsr   operatorr   numpyr   pandasr  r   r  r   r   r   r   r	   r
   r   r   r   r   r   r   r   r0   r   r   r^  r.   r   r   <module>r     s                               E E E E E E E E E E E E               = = = = = = = =(5 5 5 5 5 5 5 5(G G G G Gk G G GTa a a a a' a a aHO1 O1 O1 O1 O1y O1 O1 O1 O1 O1r   