
    e                       d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
 ddlZddlmZmZmZmZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZ g dZ ej8                  dddd       ej8                  dddd       ej8                  dddd       ej8                  dddd       ej8                  dddd       ej8                  dddd       ej8                  dddd       ej8                  dddd       ej8                  dddd       ej8                  dddd       ej8                  dddd      dZdZdZ e  e! e"e            D  cg c]  } e|    | dz
  dz  f c}       Z#de#d<    ejH                  dez   dz         Z% ejH                  dez   dz         Z&d`dZ'dadZ(e%dfdZ)e*e%dfdZ+d Z, G d  d!ej8                        Z-d" Z.d# Z/d$ Z0dbd%Z1 ejd                  d&      Z3 ejd                  d'      Z4 ejd                  d(      Z5dcd)Z6d* Z7ddd+Z8d, Z9d- Z:ded.Z;d/ Z<dfd0Z=d1 Z>d2 Z?dgd3Z@d4 ZAdhd5ZBd6 ZCd7 ZDdid8ZEd9 ZFd: ZGd; ZHdjd<ZI eJ eKeLej                  j                  d=      dd>             d?k\  rej                  ZId@ ZPdkdAZQdB ZRdC ZSdldDZTdE ZUdF ZVdmdGZWdH ZXdndIZYdJ ZZdK Z[dodLZ\dM Z]dN Z^djdOZ_dpdPZ`dQ ZadR ZbdS ZcdqdTZddrdUZedafdV ZgdW ZhdX ZidsdYZjdtdZZkdtd[Zldud\Zmd] Zn G d^ d_eo      Zpyc c} w )vz
functions.py -  Miscellaneous functions with no other home
Copyright 2010  Luke Campagnola
Distributed under MIT/X11 license. See license.txt for more information.
    )divisionN)OrderedDict   )QtdebuggetConfigOptionreload)	MetaArray)QT_LIBQtCoreQtGui)getCupy)getNumbaFunctions)0siScalesiFormatsiParsesiEvalsiApplyColormkColormkBrushmkPenhsvColorCIELabColorcolorCIELabcolorDistance
colorTuplecolorStrintColorglColormakeArrowPatheqaffineSliceCoordsaffineSliceinterweaveArraysinterpolateArraysubArraytransformToArraytransformCoordinatessolve3DTransformsolveBilinearTransformclip_scalar
clip_arrayrescaleDataapplyLookupTablemakeRGBAmakeARGB
makeQImageimageToArraycolorToAlphagaussianFilter
downsamplearrayToQPathisocurve
traceImage
isosurfaceinvertQTransformpseudoScattertoposort
disconnectSignalBlock         d   )bgrcmykwdlsu   yzafpnµm kMGTPEZYzyzafpnum kMGTPEZY      iuzb(?P<number>[+-]?((((\d+(\.\d*)?)|(\d*\.\d+))([eE][+-]?\d+)?)|((?i:nan)|(inf))))\s*((?P<siPrefix>[uz]?)(?P<suffix>\w.*))?$z&(?P<number>[+-]?\d+)\s*(?P<siPrefix>[uz]?)(?P<suffix>.*)$c                    t        | t        j                        rt        |       } 	 t	        j
                  |       sy	 t        |       |k  rd}n[t        t        t	        j                  t	        j                  t        |             t	        j                  d      z        dd            }|dk(  rd}n.|dk  s|dkD  r	d	|d
z  z  }n|rt        |dz      }nt        |dz      }d|z  }d|z  }||fS #   xY w)u   
    Return the recommended scale factor and SI prefix string for x.
    
    Example::
    
        siScale(0.0001)   # returns (1e6, 'μ')
        # This indicates that the number 0.0001 is best represented as 0.0001 * 1e6 = 100 μUnits
    )r    r   i  g      "g      "@rS   irO   ze%drP   g      $@)
isinstancedecimalDecimalfloatmathisfiniteabsintr,   floorlogSI_PREFIXESSI_PREFIXES_ASCII)xminValallowUnicoderH   prefm1ps          5/usr/lib/python3/dist-packages/pyqtgraph/functions.pyr   r   I   s     !W__%!H}}Q   1vDJJtxxA'7'FGsSTAv	
R1q5!}qs#D$QqS)D	ABRAt9#s   C. .C1c                    |du rd}|du rd}t        | ||      \  }}t        |      dkD  r|d   dk(  s||z   }|dt        |      z   dz   }	|	| |z  ||fz  S |r	|d	z   |z   }
nd
}
dt        |      z   dz   }	|	| |z  |||
t        |||||      fz  S )u   
    Return the number x formatted in engineering notation with SI prefix.
    
    Example::
        siFormat(0.0001, suffix='V')  # returns "100 μV"
    T FrS   r   ez%.zg%s%s   ±z +/- z	g%s%s%s%s)	precisionsuffixspacerb   )r   lenstrr   )ra   rl   rm   rn   errorrb   rc   rf   rd   fmt	plusminuss              rg   r   r   l   s     }~ 6<0IQIMd1gnt|}S^#g-ac4(((u,IIS^#k1ac4HUi`fns  }C  5D  E  E  	E    c                    | j                         } |Dt        |      dkD  r6| t        |       d |k7  rt        d| d|d      | dt        |        dz   } |dk(  r| dz  } |j                  |       }|t        d| z        	 |j	                  d	      }|	 |j	                  d
      }n|}|j	                  d      |dn||dfS |fS # t
        $ r d}Y Aw xY w# t
        $ r d}Y ;w xY w)u  Convert a value written in SI notation to a tuple (number, si_prefix, suffix).

    Example::

        siParse('100 µV")  # returns ('100', 'µ', 'V')

    Note that in the above example, the µ symbol is the "micro sign" (UTF-8
    0xC2B5), as opposed to the Greek letter mu (UTF-8 0xCEBC).

    Parameters
    ----------
    s : str
        The string to parse.
    regex : re.Pattern, optional
        Compiled regular expression object for parsing. The default is a
        general-purpose regex for parsing floating point expressions,
        potentially containing an SI prefix and a suffix.
    suffix : str, optional
        Suffix to check for in ``s``. The default (None) indicates there may or
        may not be a suffix contained in the string and it is returned if
        found. An empty string ``""`` is handled differently: if the string
        contains a suffix, it is discarded. This enables interpreting
        characters following the numerical value as an SI prefix.
    Nr   zString 'z%' does not have the expected suffix ''XrS   zCannot parse number "%s"siPrefixrm   number)stripro   
ValueErrormatchgroup
IndexError)rN   regexrm   rH   sipsufs         rg   r   r      s   2 	
	Ac&kAoc&k\]v%UVX^_``mF|s" |	SAAy3a788ggj! ~	''(#C 778CKbS"TTQTTT    	C	s$   C C CCC'&C'c                 N    t        | ||      \  }}} ||      }t        ||      S )u   
    Convert a value written in SI notation to its equivalent prefixless value.

    Example::
    
        siEval("100 μV")  # returns 0.0001
    )rm   )r   r   )rN   typr   rm   valsiprefixvs          rg   r   r      s/     $AuV<C6CA1hrt   c                 \    |dk7  r	t         |   nd}|dkD  r| d|z  z  S |dk  r	| d| z  z  S | S )z
    rS   r   
   )SI_PREFIX_EXPONENTS)r   r   ns      rg   r   r      sH     *2RH%QA1uRU{	
QR!V|
rt   c                       e Zd Zd Zd Zd Zy)r   c                 P    t         j                  j                  | t        |        y N)r   QColor__init__r   selfargss     rg   r   zColor.__init__   s    dGTN3rt   c                 "    | j                         S )z-Return (r,g,b,a) normalized for use in opengl)getRgbFr   s    rg   r    zColor.glColor   s    ||~rt   c                 n     | j                   | j                  | j                  | j                  f|          S r   )redgreenbluealpha)r   inds     rg   __getitem__zColor.__getitem__   s+    A$**dii<SACCrt   N)__name__
__module____qualname__r   r    r    rt   rg   r   r      s    4Drt   r   c                     dt        |       z  }t        |       dk(  rt        | d   t               r| d   }t        |      dk(  r	 t        j                  t
        |         S |d   dk(  rht        |      dk  rZ|dd }t        |      dk  r"d	j                  |D cg c]  }||z   	 c}      }t        j                  t        j                  |       S t        j                  |      }|j                         r|S t        d
| d      t        | d   t        j                        rt        j                  | d         S t        j                  t        | d         t        j                        rt!        | d   dz        x}x}}d}nt#        | d   d      r`t        | d         dk(  r| d   \  }}}d}nt        | d         dk(  r| d   \  }}}}nt        | d         dk(  rt%        | d    S t'        |      t        j                  t        | d         t        j(                        rt%        | d         S t'        |      t        |       dk(  r	| \  }}}d}n!t        |       dk(  r| \  }}}}nt'        |      ||||fD cg c]$  }t        j*                  |      rt!        |      nd& } }t        j                  |  S # t        $ r t        d|z        dw xY wc c}w c c}w )a  
    Convenience function for constructing QColor from a variety of argument 
    types. Accepted arguments are:
    
    ================ ================================================
     'c'             one of: r, g, b, c, m, y, k, w or an SVG color keyword
     R, G, B, [A]    integers 0-255
     (R, G, B, [A])  tuple of integers 0-255
     float           greyscale, 0.0-1.0
     int             see :func:`intColor() <pyqtgraph.intColor>`
     (int, hues)     see :func:`intColor() <pyqtgraph.intColor>`
     "#RGB"         
     "#RGBA"         
     "#RRGGBB"       
     "#RRGGBBAA"     
     QColor          QColor instance; makes a copy.
    ================ ================================================
    z&Not sure how to make a color from "%s"r   r   zNo color named "%s"N#r      rS   zUnable to convert z
 to QColorr@   __len__rP         )rp   ro   rU   r   r   ColorsKeyErrorr{   joinbytesfromhexisValidnp
issubdtypetypefloatingr\   hasattrr   	TypeErrorintegerrZ   )	r   errrG   ra   qcolrF   rE   rD   as	            rg   r   r      s   & 3SY
>C
4yA~d1gs#QA1v{J <<q	22 ts{s1v{abEq6A: 21Q 23A||U]]1%566 ||A<<>K #5aS
!CDDQ.<<Q((]]4Q="++6DGcM**A*AAT!Wi(47|q q'1aT!W"!!W
1aT!W"a))n$]]4Q="**5DG$$C. 	Ta1a	Ta
1an67Aq\Bbkk!nCF!+BDB<<U   J$%:Q%>?TIJ !3D Cs   J9 K<)K9Kc                  n   d|v r|d   }nt        |       dk(  rp| d   }|7t        j                  t        j                  j
                  j                        S t        |t        j                        rt        j                  |      S |}nt        |       dkD  r| }t        j                  t                    S )z
    | Convenience function for constructing Brush.
    | This function always constructs a solid brush and accepts the same arguments as :func:`mkColor() <pyqtgraph.mkColor>`
    | Calling mkBrush(None) returns an invisible brush.
    colorr   r   )	ro   r   QBrushr   r   
BrushStyleNoBrushrU   r   )r   kwdsr   args       rg   r   r   .  s     $W	Ta1g;<<		 4 4 < <==U\\*<<$$E	TQ<<''rt   c                     |j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  d	d      }t        |       dk(  rx| d
   }t        |t              rt	        di |S t        |t
        j                        rt        j                  |      S |%t        j                  j                  j                  }n|}t        |       dkD  r| }|t        d      }|	t        | }nt        |      }t        j                  t        j                  |      |      }	|	j                  |       ||	j                  |       ||	j!                  |       |dkD  r3|	j#                  t        j                  j$                  j&                         |	S )az  
    Convenience function for constructing QPen. 
    
    Examples::
    
        mkPen(color)
        mkPen(color, width=2)
        mkPen(cosmetic=False, width=4.5, color='r')
        mkPen({'color': "#FF0", width: 2})
        mkPen(None)   # (no pen)
    
    In these examples, *color* may be replaced with any arguments accepted by :func:`mkColor() <pyqtgraph.mkColor>`    r   Nwidthr   styledashcosmeticThsvr   rM   g      @r   )getro   rU   dictr   r   QPenr   r   PenStyleNoPenr   r   r   setCosmeticsetStylesetDashPatternsetCapStylePenCapStyleRoundCap)
r   kargsr   r   r   r   r   r   r   pens
             rg   r   r   C  ss    IIgt$EIIgq!EIIgt$E99VT"DyyT*H
))E4
 C
4yA~1gc4 <3<c5::&::c?"[II&&,,EE
4y1}}
#
**U\\%(%
0COOHU4  s{		--667Jrt   c                 F    t         j                  j                  | |||      S )zEGenerate a QColor from HSVa values. (all arguments are float 0.0-1.0))r   r   fromHsvF)huesatr   r   s       rg   r   r   }  s    <<  c366rt   ))g7d?g,C?gv?)gz6?g,C?g]m{?)gN@aÓ?g2%䃾?"~j?))g!rh	@g)0gCl߿)g鷯gjt?g_L?)gPkw?g&1ʿgx?)r         ?gw-!l?c                    t        j                  d| dz   dz        }|dxx   |dz  z  cc<   |dxx   |dz  z  cc<   t        |      D ]$  \  }}|dkD  r||   dz  ||<   ||   d	z
  d
z  ||<   & t        |z  }t        |z  }t        j
                  d      }t        |dd       D ]!  \  }}|dkD  rd|dz  z  dz
  ||<   d|z  ||<   # t        |dd      }t        j                  j                  g || S )u  
    Generates as QColor from CIE L*a*b* values.
    
    Parameters
    ----------
        L: float
            Lightness value ranging from 0 to 100
        a, b: float
            (green/red) and (blue/yellow) coordinates, typically -127 to +127.
        alpha: float, optional
            Opacity, ranging from 0 to 1

    Notes
    -----
    The CIE L*a*b* color space parametrizes color in terms of a luminance `L` 
    and the `a` and `b` coordinates that locate the hue in terms of
    a "green to red" and a "blue to yellow" axis.
    
    These coordinates seek to parametrize human color preception in such a way
    that the Euclidean distance between the coordinates of two colors represents
    the visual difference between these colors. In particular, the difference
    
    ΔE = sqrt( (L1-L2)² + (a1-a2)² + (b1-b2)² ) = 2.3
    
    is considered the smallest "just noticeable difference" between colors.
    
    This simple equation represents the CIE76 standard. Later standards CIE94
    and CIE2000 refine the difference calculation ΔE, while maintaining the 
    L*a*b* coordinates.
    
    Alternative (and arguably more accurate) methods exist to quantify color
    difference, but the CIELab color space remains a convenient approximation.
    
    Under a known illumination, assumed to be white standard illuminant D65 
    here, a CIELab color induces a response in the human eye
    that is described by the tristimulus value XYZ. Once this is known, an
    sRGB color can be calculated to induce the same response.
    
    More information and underlying mathematics can be found in e.g.
    "CIELab Color Space" by Gernot Hoffmann, available at
    http://docs-hoffmann.de/cielab03022003.pdf .
    
    Also see :func:`colorDistance() <pyqtgraph.colorDistance>`.
    rP      t   r     r   rB   gI_{?{a?S%@Ngsåi?zG?g?)\(?ףp=
)@        r   )
r   full	enumerateVECTOR_XYZnMATRIX_RGB_FROM_XYZzerosr-   r   r   fromRgbF)	Lr   rD   r   vec_XYZidxr   vec_RGBarr_sRGBs	            rg   r   r     s#   \ gga1b5#'GAJ!c'JAJ!c'Jg& ;S="3<?GCL#CL61U:GCL	;
 G#G #W,Gxx{Hwr{, (S?!C%L058HSM!CKHSM	(
 8S#/H<<  484U44rt   c                    | j                         dd }t        j                  d      }t        |      D ]!  \  }}|dkD  r|dz   dz  dz  ||<   |dz  ||<   # t        |z  }|t
        z  }t        |      D ]$  \  }}|dkD  r||   d	z  ||<   d
||   z  dz   ||<   & t        j                  d|d   z  dz
  d|d   |d   z
  z  d|d   |d   z
  z  g      }|S )a  
    Describes a QColor by an array of CIE L*a*b* values.
    Also see :func:`CIELabColor() <pyqtgraph.CIELabColor>` .

    Parameters
    ----------
    qcol: QColor
        QColor to be converted

    Returns
    -------
    np.ndarray 
        Color coordinates `[L, a, b]`.
    NrP   g}ڵ?r   r   g333333@r   g2#?gUUUUUU?r   r   r   r   r   r   r   rB   r   )r   r   r   r   MATRIX_XYZ_FROM_RGBr   array)r   srgbr   r   r   r   vec_XYZ1vec_Labs           rg   r   r     s    <<>"1DhhqkGt% 'S#$ Y-3GCL;GCL	' "G+G$Hh' 9S>$SMC0HSM!(3-/&8HSM	9
 hhhqkBx{Xa[()x{Xa[()+ -G Nrt   c                 ~   |j                         }t        |       dk  rt        j                  g t              S |dk(  rqg }d}| D ]S  }t        |      }||}t        j                  t        j                  ||z
  dz              }|j                  |       |}U t        j                  |      S t        d| d      )a  
    Returns the perceptual distances between a sequence of QColors.
    See :func:`CIELabColor() <pyqtgraph.CIELabColor>` for more information.

    Parameters
    ----------
        colors: list of QColor
            Two or more colors to calculate the distances between.
        metric: str, optional
            Metric used to determined the difference. Only 'CIE76' is supported at this time,
            where a distance of 2.3 is considered a "just noticeable difference".
            The default may change as more metrics become available.
    
    Returns 
    -------
    List
        The `N-1` sequential distances between `N` colors.
    r   dtypeCIE76Nr   zMetric z is not available.)upperro   r   r   rX   r   rY   sqrtsumappendr{   )colorsmetricdistlab1collab2dEs          rg   r   r     s    & \\^F
6{Qrxx%88 	Cs#D|BFFT$YN46BKKOD	 xx~
wvh&89
::rt   c                 "    | j                         S )z&Return a tuple (R,G,B,A) from a QColor)getRgbrG   s    rg   r   r     s    88:rt   c                     dt        |       z  S )z(Generate a hex string code from a QColorz%02x%02x%02x%02x)r   r  s    rg   r   r   !  s    
1%%rt   c	                     t        |      }t        |      }t        |       ||z  z  }	|	|z  }
|	|z  }|dkD  r||||z
  |dz
  z  z  z   }n|}||
||z
  z  |z  z   }t        j                  j                  ||||      S )a  
    Creates a QColor from a single index. Useful for stepping through a predefined list of colors.
    
    The argument *index* determines which color from the set will be returned. All other arguments determine what the set of predefined colors will be
     
    Colors are chosen by cycling across hues while varying the value (brightness). 
    By default, this selects from a list of 9 hues.r   )r\   r   r   fromHsv)indexhuesvaluesmaxValueminValuemaxHueminHuer   r   r   indhindvr   hs                 rg   r   r   &  s     t9D[F
e*v
&C:D$;Dzt 1vax@AA$&-(T11A<<3511rt   c                  8    t        | i |}|j                         S )z
    Convert a color to OpenGL color format (r,g,b,a) floats 0.0-1.0
    Accepts same arguments as :func:`mkColor <pyqtgraph.mkColor>`.
    )r   r   )r   r   rG   s      rg   r    r    <  s    
 	A99;rt   c                    |.| t        j                  t        j                  |dz              z  }t        j                         }|j                  dd       |j                  | |        |A| |t        j                  t        j                  |            z  z
  }|j                  |d       n|dz  }| ||z
  t        j                  t        j                  |            z  z
  }|j                  ||        |j                  | |z   |        |j                  | |z   |       |j                  ||       |j                  | |       |j                  dd       |S )a  
    Construct a path outlining an arrow with the given dimensions.
    The arrow points in the -x direction with tip positioned at 0,0.
    If *headWidth* is supplied, it overrides *tipAngle* (in degrees).
    If *tailLen* is None, no tail will be drawn.
          ?r   )rY   tanradiansr   QPainterPathmoveTolineTo)headLen	headWidthtipAngletailLen	tailWidth	baseAnglepathinnerYs           rg   r!   r!   F  s!    dhht||HsN'CDD	DKK!KK)$9txxY0G'HHHFAS	Ii/488DLL<S3TTTFYJ'Gg%	z2Gg%y1FI&KK#KK!Krt   c           	         | |u ryt        | t              r;t        |t              r+t        j                  |       rt        j                  |      ryt        | t        j
                  t        f      }t        |t        j
                  t        f      }|s|rt        |       t        |      k7  ry|r5|r3| j                  |j                  k7  s| j                  |j                  k7  ryt        | t              rt        |t              rt        |       t        |      k7  st        |       t        |      k7  ryt        | j                               t        |j                               k7  ry| j                         D ]  \  }}t        |||         r y t        | t               st"        j$                  dk\  r>t'        | j                         |j                               D ]  \  }}t        ||      r y yt        | t(        t*        f      rht        |t(        t*        f      rRt        |       t        |      k7  st        |       t        |      k7  ryt'        | |      D ]  \  }}	t        ||	      r y y	 	 t-        j.                  t              }
|
j1                          | |k(  }	 |
|
j9                  ddd       	 t        |      }|t>        u r|S |t        j@                  u rt?        |      S t        |t        j
                        stC        |d	      rx|jE                  d
      rg	 | j                  |j                  k7  ry	 tC        |d	      r/|jE                  d
      r|jG                         jI                         S |jI                         S tK        dt=        t        |            z        # t2        $ r d}
Y w xY w# t4        t6        f$ r Y 
|
j9                  ddd       yy t;        d       t;        dt=        t        |             t=        |              t;        dt=        t        |            t=        |              xY w# 
|
j9                  ddd       w w xY w#  Y yxY w)a  The great missing equivalence function: Guaranteed evaluation to a single bool value.
    
    This function has some important differences from the == operator:
    
    1. Returns True if a IS b, even if a==b still evaluates to False.
    2. While a is b will catch the case with np.nan values, special handling is done for distinct
       float('nan') instances using math.isnan.
    3. Tests for equivalence using ==, but silently ignores some common exceptions that can occur
       (AtrtibuteError, ValueError).
    4. When comparing arrays, returns False if the array shapes are not the same.
    5. When comparing arrays of the same shape, returns True only if all elements are equal (whereas
       the == operator would return a boolean array).
    6. Collections (dict, list, etc.) must have the same type to be considered equal. One
       consequence is that comparing a dict to an OrderedDict will always return False.
    TF)rP      )moduleNz#failed to evaluate equivalence for:z  a:z  b:
implementsr
   z== operator returned type %s)&rU   rX   rY   isnanr   ndarrayr
   r   shaper   r   ro   setkeysitemsr"   r   sysversion_infoziplisttuplewarningscatch_warnings	__enter__	Exceptionr{   AttributeError__exit__printrp   boolbool_r   r$  asarrayallr   )r   rD   aIsArrbIsArrrJ   r   a_itemb_itemv1v2catcherrj   ts                rg   r"   r"   a  s     	Av !U
1e 4::a=TZZ] BJJ	23FBJJ	23F&d1ga0
 &agg0AGGqww4F !Tz!T27d1gQ3q6!1qvvx=CM)GGI 	DAqa1;	 a%)9)9V)C"%aggi"; !&&) ! !dE]#
1tUm(D7d1gQ3q6!1AY 	EBrb":	 /	..b9G qD T4.QADy	
bhhAw	Arzz	"wq,'?ALLQ\D]	ww!''! " A|$k)B99;??$$557N6T!WEFF=  	G	 '  T4. 34fc$q'lCF+fc$q'lCF+T4. 	sO   2*N( N: "Q (N73N: 6N77N: :P>	Q !AP>>Q QQ c           
      V   t        |       t        |      k7  rt        d      t        |      t        |      k7  rt        d      |D ]$  }t        |      t        |      k7  st        d       t        t        t        j
                  |             } t        |t        j                        st	        j                  |      }t        |t        j                        st	        j                  |      }t        |      fdt        |       z  z   |_	        t        j                  t        | D cg c]  }t        d|       c}         }|t        j                  df   |j                         t        ft        j                  ft        |       z  z      z  j!                  d      }||z  }|S c c}w )	zQReturn the array of coordinates used to sample data arrays in affineSlice().
    z(shape and vectors must have same length.z&origin and axes must have same length.z(each vector must be same length as axes.r   r   .r   axis)ro   r3  r.  mapr   ceilrU   r&  r   r'  mgridr/  slicenewaxis	transposeEllipsisr   )r'  originvectorsaxesr   ra   grids          rg   r#   r#     sZ    5zS\!BCC
6{c$i@AA Hq6SYFGGH RWWe$%E grzz*((7#fbjj)&!I<$s5z/1FL 88Eu5!51:567D	bjjn	 1 1 3XK2::-PSTYPZBZ4Z [	[``fg`hAKAH	 6s   'F&
c                    t        ||||      }t        t        | j                              }	|D ]  }
|	j	                  |
        t        |      t        |	      z   }| j                  |      } |dkD  r	 ddl}| j                  t        |      d }t        j                  t        |      |z   | j                        }t        j                  | D ]2  }t        f|z   } |j                   j"                  | |   |fd|i|||<   4 n?t        t        d|j                              dz   }t%        | |j                  |      |      }t        t        |j                              }g }t        t'        |            D ]M  }|j)                  |      t        |      t        |      z
  z   }|j	                  |       |j+                  |       O t        ||z         }|j                  |      }|r||fS |S # t        $ r t        d      w xY w)	a  
    Take a slice of any orientation through an array. This is useful for extracting sections of multi-dimensional arrays
    such as MRI images for viewing as 1D or 2D data.
    
    The slicing axes are aribtrary; they do not need to be orthogonal to the original data or even to each other. It is
    possible to use this function to extract arbitrary linear, rectangular, or parallelepiped shapes from within larger
    datasets. The original data is interpolated onto a new array of coordinates using either interpolateArray if order<2
    or scipy.ndimage.map_coordinates otherwise.
    
    For a graphical interface to this function, see :func:`ROI.getArrayRegion <pyqtgraph.ROI.getArrayRegion>`
    
    ==============  ====================================================================================================
    **Arguments:**
    *data*          (ndarray) the original dataset
    *shape*         the shape of the slice to take (Note the return value may have more dimensions than len(shape))
    *origin*        the location in the original dataset that will become the origin of the sliced data.
    *vectors*       list of unit vectors which point in the direction of the slice axes. Each vector must have the same 
                    length as *axes*. If the vectors are not unit length, the result will be scaled relative to the 
                    original data. If the vectors are not orthogonal, the result will be sheared relative to the 
                    original data.
    *axes*          The axes in the original dataset which correspond to the slice *vectors*
    *order*         The order of spline interpolation. Default is 1 (linear). See scipy.ndimage.map_coordinates
                    for more information.
    *returnCoords*  If True, return a tuple (result, coords) where coords is the array of coordinates used to select
                    values from the original dataset.
    *All extra keyword arguments are passed to scipy.ndimage.map_coordinates.*
    --------------------------------------------------------------------------------------------------------------------
    ==============  ====================================================================================================
    
    Note the following must be true: 
        
        | len(shape) == len(vectors) 
        | len(origin) == len(axes) == len(vectors[i])
        
    Example: start with a 4D fMRI data set, take a diagonal-planar slice out of the last 3 axes
        
        * data = array with dims (time, x, y, z) = (100, 40, 40, 40)
        * The plane to pull out is perpendicular to the vector (x,y,z) = (1,1,1) 
        * The origin of the slice will be at (x,y,z) = (40, 0, 0)
        * We will slice a 20x20 plane from each timepoint, giving a final shape (100, 20, 20)
        
    The call for this example would look like::
        
        affineSlice(data, shape=(20,20), origin=(40,0,0), vectors=((-1, 1, 0), (-1, 0, 1)), axes=(1,2,3))
    
    r   r   Nz]Interpolating with order > 1 requires the scipy.ndimage module, but it could not be imported.r   orderr   )rS  )r#   r.  rangendimremover/  rL  scipy.ndimageImportErrorr'  ro   r   emptyr   ndindexrM  ndimagemap_coordinatesr&   minr  r   )datar'  rN  rO  rP  rS  returnCoordsr   ra   trAxaxtr1scipy
extraShapeoutputindsr   trtrbitr2s                        rg   r$   r$     s   ^ 	%$7A dii !D B
+d
#C>>#D qy	 
 ZZD	
+
%,34::FJJ
+ 	\D+$C7%--77S	1[E[UZ[F3K	\ 5AFF#$t+!$BuE	eFKK 	!B
C3t9 iilc%jT23
		#

3 B-C c"F{9  	}~~	s   3G. .Hc                      t        d | D              }t        j                  |f| d   j                        }t	        |       }t        |       D ]  \  }}|||d|<    |S )a  
    Parameters
    ----------

    args : numpy.ndarray
           series of 1D numpy arrays of the same length and dtype
    
    Returns
    -------
    numpy.ndarray
        A numpy array with all the input numpy arrays interwoven

    Examples
    --------

    >>> result = interweaveArrays(numpy.ndarray([0, 2, 4]), numpy.ndarray([1, 3, 5]))
    >>> result
    array([0, 1, 2, 3, 4, 5])
    c              3   4   K   | ]  }|j                     y wr   )size).0ra   s     rg   	<genexpr>z#interweaveArrays.<locals>.<genexpr>Q  s     $!qvv$s   r   r   N)r   r   rZ  r   ro   r   )r   rn  resultr   r  r   s         rg   r%   r%   <  sc    * $t$$DXXtgT!W]]3FD	A!$ !u uxax!Mrt   c           	      J   |dvrt        d|z        t        j                         }| j                  }|j                  d   }||kD  rt        d      t        j                  |j                  dd t              }|dk(  rt        j                  |      j                  t              }t        |      D ]7  }	|d|	f   dk\  |d|	f   | j                  |	   d	z
  k  z  }
d|d|	f   |
 <   ||
z  }9 | t        t        |j                  d         D cg c]	  }|d|f    c}         }nL|d	k(  rFt        j                  t        d|d	z         f|z     }t        j                   |      j                  t              }|d	z   }t        j"                  |t        j$                  df   |t        j$                  df   g      }g }t        |      D ]  }	|d|	f   dk\  |d|	f   | j                  |	   d	z
  k  z  }
||
z  }|
|d|	f   | j                  |	   k  z  }
|d|	f   ||	      }d||dk  <   d||| j                  |	   k\  <   |j'                  |         |        | t        |         } |        t        j(                  |f|j                  z   t*              }||z
  }t        |      D ]  }	||	   j-                  ||	   j                  d
|j                  d	z
  z  z         }||d|	f   z  d	|z
  d	|d|	f   z
  z  z   }|j-                  |j                  d
|j                  d	z
  |j                  z
  z  z         }|||	<    t        j.                  |d      }||z  }t        |      D ]  }|j1                  d      }  |        |j                  dkD  r|| <   n	|du r|dd  |        S c c}w )a
  
    N-dimensional interpolation similar to scipy.ndimage.map_coordinates.
    
    This function returns linearly-interpolated values sampled from a regular
    grid of data. It differs from `ndimage.map_coordinates` by allowing broadcasting
    within the input array.
    
    ==============  ===========================================================================================
    **Arguments:**
    *data*          Array of any shape containing the values to be interpolated.
    *x*             Array with (shape[-1] <= data.ndim) containing the locations within *data* to interpolate.
                    (note: the axes for this argument are transposed relative to the same argument for
                    `ndimage.map_coordinates`).
    *default*       Value to return for locations in *x* that are outside the bounds of *data*.
    *order*         Order of interpolation: 0=nearest, 1=linear.
    ==============  ===========================================================================================
    
    Returns array of shape (x.shape[:-1] + data.shape[x.shape[-1]:])
    
    For example, assume we have the following 2D image data::
    
        >>> data = np.array([[1,   2,   4  ],
                             [10,  20,  40 ],
                             [100, 200, 400]])
        
    To compute a single interpolated point from this data::
        
        >>> x = np.array([(0.5, 0.5)])
        >>> interpolateArray(data, x)
        array([ 8.25])
        
    To compute a 1D list of interpolated locations:: 
        
        >>> x = np.array([(0.5, 0.5),
                          (1.0, 1.0),
                          (1.0, 2.0),
                          (1.5, 0.0)])
        >>> interpolateArray(data, x)
        array([  8.25,  20.  ,  40.  ,  55.  ])
        
    To compute a 2D array of interpolated locations::
    
        >>> x = np.array([[(0.5, 0.5), (1.0, 2.0)],
                          [(1.0, 1.0), (1.5, 0.0)]])
        >>> interpolateArray(data, x)
        array([[  8.25,  40.  ],
               [ 20.  ,  55.  ]])
               
    ..and so on. The *x* argument may have any shape as long as 
    ```x.shape[-1] <= data.ndim```. In the case that 
    ```x.shape[-1] < data.ndim```, then the remaining axes are simply 
    broadcasted as usual. For example, we can interpolate one location
    from an entire row of the data::
    
        >>> x = np.array([[0.5]])
        >>> interpolateArray(data, x)
        array([[  5.5,  11. ,  22. ]])

    This is useful for interpolating from arrays of colors, vertexes, etc.
    r   r   z/interpolateArray requires order=0 or 1 (got %s)z3x.shape[-1] must be less than or equal to data.ndimNr   r   .r   rD  rE  F)r{   r   ProfilerrV  r'  r   r   onesr7  roundastyper\   rU  r/  rI  rJ  r]   concatenaterK  r   rZ  rX   reshapeprodr   )r_  ra   defaultrS  profndmd	totalMaskxindsrb  maskrj  rq  fieldsxminxmaxindexes	fieldInds	axisIndex	fieldDatarN   dxf1saxs                           rg   r&   r&   Y  s   z FJURSS>>D	B	
B	BwMNND1Iz""3') 	B#b&MQ&5R=DJJrN1<L+LMD#$E#b&M4% I		
 e5R3IJaU3q5\JKL	! 557+-23xx{!!#&ax..$rzz3"7bjj#o9N!OP	) 	(BRLA%!CF)tzz"~a7G*GHDI
 T#b&\DJJrN23DBr
3I'(Ii!m$56Ii4::b>12Y'	( 	 y)*	 HHbUY__,E:X) 	B##F2J$4$4tRWWQY7G$GHBr#b&z/QrTa3r6
l$;;C++cii$!&&(3882C*DDECAbE		
 GGAAQr 	(AZZQZ'F	( 	F~~$	zF1IFMi Ks   N 
c                 V   t        j                  |       |d } t        |      }| j                  dd }t	        | j
                  ddd         }|d   }|ddd   D ]  }|j                  ||z          t        |ddd         }t        j                  | ||z   || j                        S )a  
    Unpack a sub-array from *data* using the specified offset, shape, and stride.
    
    Note that *stride* is specified in array elements, not bytes.
    For example, we have a 2x3 array packed in a 1D array as follows::
    
        data = [_, _, 00, 01, 02, _, 10, 11, 12, _]
        
    Then we can unpack the sub-array with this call::
    
        subArray(data, offset=2, shape=(2, 3), stride=(4, 1))
        
    ..which returns::
    
        [[00, 01, 02],
         [10, 11, 12]]
         
    This function operates only on the first axis of *data*. So changing 
    the input in the example above to have shape (10, 7) would cause the
    output to have shape (2, 3, 7).
    Nr   rt  )bufferr'  stridesr   )	r   ascontiguousarrayr/  r'  r.  r  r   r&  r   )r_  offsetr'  stridere  r  itemsizerN   s           rg   r'   r'     s    , %fg.D%LEABJ4<<"%&Gr{HAErE] %x!|$%GDbDM"G::Tz)97RVR\R\]]rt   c                 $   t        | t        j                        rt        j                  | j                         | j                         | j                         g| j                         | j                         | j                         g| j                         | j                         | j                         gg      S t        | t        j                        r3t        j                  | j                               j!                  dd      S t#        d      )a  
    Given a QTransform, return a 3x3 numpy array.
    Given a QMatrix4x4, return a 4x4 numpy array.
    
    Example: map an array of x,y coordinates through a transform::
    
        ## coordinates to map are (1,5), (2,6), (3,7), and (4,8)
        coords = np.array([[1,2,3,4], [5,6,7,8], [1,1,1,1]])  # the extra '1' coordinate is needed for translation to work
        
        ## Make an example transform
        tr = QtGui.QTransform()
        tr.translate(3,4)
        tr.scale(2, 0.1)
        
        ## convert to array
        m = pg.transformToArray()[:2]  # ignore the perspective portion of the transformation
        
        ## map coordinates through transform
        mapped = np.dot(m, coords)
    r   z;Transform argument must be either QTransform or QMatrix4x4.)rU   r   
QTransformr   r   m11m21m31m12m22m32m13m23m33
QMatrix4x4
copyDataTorz  r3  )rh  s    rg   r(   r(     s    4 "e&&'xx"&&(BFFHbffh7"&&(BFFHbffh9WZ\Z`Z`ZbdfdjdjdlnpntntnvYwxyy	B((	)xx(00155UVVrt   c           
      :   |rB|j                  |j                  dz
  ft        t        d|j                  dz
              z         }|j                  d   }t        | t        j                        r| }n t        |       }|d|j                  d   dz
   }|j                  dk(  rE|dk(  r@t        j                  d      }|ddddf   |ddddf<   |dddf   |dddf<   d|d<   |}|j                  dk(  r@|dk(  r;t        j                  d      }|ddddf   |ddddf<   |dddf   |dddf<   |}|j                  |j                  d	|j                  dz
  z  z         }|t        j                  d
f   }|dddf   }|ddddf   }t        j                         5  t        j                  dt                ||z  j#                  d      }ddd       |z  }|r1|j                  t        t        d|j                              dz         }|S # 1 sw Y   CxY w)a  
    Map a set of 2D or 3D coordinates through a QTransform or QMatrix4x4.
    The shape of coords must be (2,...) or (3,...)
    The mapping will _ignore_ any perspective transformations.
    
    For coordinate arrays with ndim=2, this is basically equivalent to matrix multiplication.
    Most arrays, however, prefer to put the coordinate axis at the end (eg. shape=(...,3)). To 
    allow this, use transpose=True.
    
    r   r   Nr   rP   rP   )rP   r   r   r   r   rD  .rt  ignorerE  rT  )rL  rV  r/  rU  r'  rU   r   r&  r(   r   rZ  rz  rK  r0  r1  simplefilterRuntimeWarningr   )rh  coordsrL  r~  rH   m2	translatemappeds           rg   r)   r)   #  s&    !!6;;q="2U56;;q=;Q5R"RS	aB"bjj!R mqwwqz!| 	ww%B!GXXe_rr"1"uX2A2rr6
bqbdG2A2q5	3 	ww%B!GXXe_RaRU81RaR4BQBqD'1Q3 	
		!''D&++a-001ABJJO$F !B$I	!SbS&	A 
	 	 	" (h7F(Q'( iF!!%a(<"="DEM( (s   0HHc           
      ^   ddl }g }| |fD ]  }t        |t        j                        r9t        j                  dt
              }|ddddf   |ddddf<   d|dddf<   nct        j                  t        d      D cg c];  }||   j                         ||   j                         ||   j                         dg= c}      }|j                  |        t        j                  d      }t        d      D ].  }|j                  j                  |d   |d   dd|f         ||<   0 |S c c}w )	z
    Find a 3D transformation matrix that maps points1 onto points2.
    Points must be specified as either lists of 4 Vectors or 
    (4, 3) arrays.
    r   N)r   r   r   rP   r   r   r   )numpy.linalgrU   r   r&  rZ  rX   r   rU  ra   rI   zr   r   linalgsolve)points1points2numpyptsinpArj  matrixs           rg   r*   r*   `  s    
C! c2::&e,A!BQB$iAadGAacF5QR8Ta3q688:s1vxxz3q688:qATUA

1 XXe_F1X <LL&&s1vs1vac{;q	< M Us   =A D*
c           	      F   ddl }t        j                  t        d      D cg c]O  }| |   j	                         | |   j                         z  | |   j	                         | |   j                         dgQ c}      }t        j                  t        d      D cg c](  }||   j	                         ||   j                         g* c}      }t        j                  d      }t        d      D ](  }|j                  j                  ||dd|f         ||<   * |S c c}w c c}w )a  
    Find a bilinear transformation matrix (2x4) that maps points1 onto points2.
    Points must be specified as a list of 4 Vector, Point, QPointF, etc.
    
    To use this matrix to map a point [x,y]::
    
        mapped = np.dot(matrix, [x*y, x, y, 1])
    r   Nr   r   )r   r   r   )	r  r   r   rU  ra   rI   r   r  r  )r  r  r  rj  r  Br  s          rg   r+   r+   y  s      	^cde^fgYZ71:<<>'!*,,.0'!*,,.'!*,,.RSTghA
E!HEq71:<<>71:<<>2EFA XXe_F1X 2LL&&q!AaC&1q	2 M hEs   AD-Dc                 "    | |k  r|S | |kD  r|S | S )z? convenience function to avoid using np.clip for scalar values r   )r   vminvmaxs      rg   r,   r,     s    :4>3:4>3>rt   c                 N   ||t        j                  | |||      S |,t         j                  j                  j	                  | ||      S |,t         j                  j                  j                  | ||      S t         j                  j                  j                  | |||      S )Nout)r   clipcoreumathminimummaximum)arrr  r  r  s       rg   r-   r-     s    
 |wwsD$C00|ww}}$$S$C$88	ww}}$$S$C$88ww}}!!#tTs!;;rt   .r   )r      c                    t        j                  | |      }d}| j                  j                  dv r|j                  dv r t        j                  | j                        }t        |t         j                        r|j                  d      n|}	||j                  |	z
  z  ||j                  |	z
  z  f}
|
d   |
d   k  r
|
d   |
d   f}
t        j                  t         j                        }|j                  |
d   k  xr |
d   |j                  k  }|r0|.|D cg c]#  }t        ||j                  |j                        % }}t        j                  | |gddgd	gd
dggd|gdd      }|5  |D ]P  \  }}||d<   ||z  }||z  }||r |j                  t         j                        }n|}t        ||d   |d   |       R 	 ddd       |S c c}w # 1 sw Y   |S xY w)z(Refer to documentation for rescaleData()r   Fuir   r   Nexternal_loopbufferedreadonly	writeonlyno_broadcastunsafei   )flagsop_flags	op_dtypescasting
buffersize.r  )r   
empty_liker   kindiinforU   ry   itemr^  maxint32r,   nditerrx  r-   )data_inscaler  
work_dtype	out_dtyper  data_out
fits_int32lim_inlo
dst_boundslim32r   itra   rI   yins                    rg   _rescaleData_nditerr    s   }}WI6H J}}T!inn&<
 '--()&"))<V[[^&fjj2o.b0II
a=:a=(#A
15J"YYA.L:a=5993L
$* CGGQK599eii8GDG	GX&"J/!l[.$ABZ(
B 
 9 	9DAqAcFKAJA ((288,CC3Qaa8	99 O1 H9 Os   (G*G;GGc                 4   || j                   }nt        j                   |      }|j                  dv rt        j                  |      }||j                  |j
                  f}t        |d   |j                        t	        |d   |j
                        f}|D cg c]  }t        j                  |       }}t        j                  | t        j                        rt        j                  }nt        j                  }t               }	|	r[|	j                  |       |	k(  rG| j                  |d      }
|
|z  }
|
|z  }
|t        |
|d   |d   |
       |
j                  |d      S t               }|r||j!                  | ||||      S t#        | |||||      S c c}w )zReturn data rescaled and optionally cast to a new dtype.

    The scaling operation is::

        data => (data-offset) * scale
    r  r   r   T)copyr  F)r   r   r  r  r^  r  rY   trunccan_castfloat32float64r   get_array_modulerx  r-   r   r.   r  )r_  r  r  r   r  r  limra   r  cpr  numba_fns               rg   r.   r.     ss    }JJ	HHUO	~~hhy!<77CGG#D47CGG$c$q'377&;; (,,!

1,,	{{4$ZZ
ZZ
	B	b!!$'2- ;;z;5FE xa$q'x@ yu55 "HD$##D%DIItUFJ	4PP9 -s   Fc           	      8   | j                   j                  dvr| j                  t              } t	               }|rI|j                  |       |k(  r5|j                  ||j                  | d|j                  d   dz
        d      S t        j                  || dd      S )a  
    Uses values in *data* as indexes to select values from *lut*.
    The returned data has shape data.shape + lut.shape[1:]
    
    Note: color gradient lookup tables can be generated using GradientWidget.

    Parameters
    ----------
    data : np.ndarray
    lut : np.ndarray
        Either cupy or numpy arrays are accepted, though this function has only
        consistently behaved correctly on windows with cuda toolkit version >= 11.1.
    )rj  rQ   r   r   rE  r  )rF  mode)
r   r  rx  r\   r   r  taker  r'  r   )r_  lutr  s      rg   r/   r/     s     zzj({{3	B	b!!$'2-wwsBGGD!SYYq\A-=>QwGGwwsDqv66rt   c                  "    d|d<   t        | i |S )z)Equivalent to makeARGB(..., useRGBA=True)TuseRGBA)r1   )r   r   s     rg   r0   r0   .  s    DOT"T""rt   c                 F   t               }|r|j                  |       nt        }t        j                         }	| j
                  dvrt        d      | j
                  dk(  r| j                  d   dkD  rt        d      |'t        ||j                        s|j                  |      }|| j                  j                  dk(  r'|j                  d	d| j                  d
z  z  dz
  g      }n~| j                  j                  dk(  r-d| j                  d
z  dz
  z  }
|j                  |
 |
dz
  g      }n8| j                  j                  dk(  r|j                  d	dg      }nt        d      t        ||j                        s|j                  |      }|j                  |j                         }|j
                  dk(  r|j                  d	   dk7  rt        d      |j
                  dk(  rE||j
                  dkD  rt        d      |j                  | j                  d   dfk7  r,t        d      t        dt#        |j                        z         |	d       |||j                  d	   }nd}||j$                  }n!|j'                  |j                  d	   dz
        }d}|rk| j                  j                  dk(  rR|j)                  | j+                               r3|j)                  |       }| j
                  dkD  r|j-                  |d      }|%t        ||j                        r|j
                  dk(  r|j                  d	   | j                  d   k7  rt        d      |j/                  | j                  t0              }t3        | j                  d         D ]N  }||   \  }}||k(  r|j5                  |d|z        }||z
  }|d	k(  rdn|}t7        | d|f   ||z  ||      |d|f<   P |} nI|\  }}|d	k7  s||k7  r:||k(  r|j5                  |d|z        }||z
  }|d	k(  rdn|}t7        | ||z  ||      }  |	d       |t9        | |      } nE| j                  |j$                  k7  r,|j;                  | d	d      j                  |j$                        }  |	d       |.|j/                  | j                  dd dz   |j$                        }n|} |	d       |rg d }nt<        j>                  d!k(  rg d"}ng d#}tA        || ||      }|rn| j
                  dk(  rt3        d      D ]  }| |d||   f<    n]| j                  d   dk(  rt3        d      D ]  }| d$   |d||   f<    n-t3        d	| j                  d         D ]  }| d|f   |d||   f<     |	d%       | j
                  dk(  r| j                  d   dk(  rd&}nd'}|s
d|d|d   f<   |Td&}||k(  rCtC        tE        t0        |jF                  jI                  d(                  d)k  rd	||dd|d   f<   n
d	|||d   f<    |	d*       ||fS )+a
  
    Convert an array of values into an ARGB array suitable for building QImages,
    OpenGL textures, etc.
    
    Returns the ARGB array (unsigned byte) and a boolean indicating whether
    there is alpha channel data. This is a two stage process:
    
        1) Rescale the data based on the values in the *levels* argument (min, max).
        2) Determine the final output by passing the rescaled values through a
           lookup table.
   
    Both stages are optional.
    
    ============== ==================================================================================
    **Arguments:**
    data           numpy array of int/float types. If 
    levels         List [min, max]; optionally rescale data before converting through the
                   lookup table. The data is rescaled such that min->0 and max->*scale*::
                   
                      rescaled = (clip(data, min, max) - min) * (*scale* / (max - min))
                   
                   It is also possible to use a 2D (N,2) array of values for levels. In this case,
                   it is assumed that each pair of min,max values in the levels array should be 
                   applied to a different subset of the input data (for example, the input data may 
                   already have RGB values and the levels are used to independently scale each 
                   channel). The use of this feature requires that levels.shape[0] == data.shape[-1].
    scale          The maximum value to which data will be rescaled before being passed through the 
                   lookup table (or returned if there is no lookup table). By default this will
                   be set to the length of the lookup table, or 255 if no lookup table is provided.
    lut            Optional lookup table (array with dtype=ubyte).
                   Values in data will be converted to color by indexing directly from lut.
                   The output data shape will be input.shape + lut.shape[1:].
                   Lookup tables can be built using ColorMap or GradientWidget.
    useRGBA        If True, the data is returned in RGBA order (useful for building OpenGL textures). 
                   The default is False, which returns in ARGB order for use with QImage 
                   (Note that 'ARGB' is a term used by the Qt documentation; the *actual* order 
                   is BGRA).
    maskNans       Enable or disable masking NaNs as transparent.
    ============== ==================================================================================
    r  zdata must be 2D or 3DrP   r   r   zdata.shape[2] must be <= 4NrQ   r   rO   r   rj  rD   z1levels argument is required for float input typesz"levels argument must have length 2z<Cannot make ARGB data when both levels and lut have ndim > 2rt  z*levels must have shape (data.shape[-1], 2)z0levels argument must be 1D or 2D (got shape=%s).zcheck inputs     o@frE  zzWhen rescaling multi-channel data, there must be the same number of levels as channels (data.shape[-1] == levels.shape[0])r   .zapply levelsr@   z	apply lutr   allocater   r   r   rP   little)r   r   r   rP   )r   r   rP   r   ).r   zreorder channelsTFr  )r   r   zalpha channel)%r   r  r   r   ru  rV  r   r'  rU   r&  r   r   r  r  r3  rx  r  reprubytemin_scalar_typer%  r^  anyrZ  r\   rU  	nextafterr.   r/   r  r+  	byteordertry_fastpath_argbr/  rG  __version__split)r_  r  levelsr  r  maskNansrf  r  xpprofilerN   r   nanMasknewDatarj  rb   maxValrngimgData	dst_orderfastpathr   s                         rg   r1   r1   4  s   R 
B&(		T	"bBnnGyy/00yyA~$**Q-!+455
z#rzz:hhsm~::??c!XXq!dmmAo"6q"89:FZZ__#DMM!Oa'(AXXr1Q3i(FZZ__#XXqe_FOPPfbjj)&!]]2::&F{{a<<?a@AA		?sxx!|Z[[<<DJJrNA..HIIJTRXR^R^M__``N }?IIaLEE {""399Q<>2 GDJJOOs*rxx
/C((4.99q=ffW2f.Gfbjj)fkkQ.>||A$**R.0  !]  ^  ^hhtzzh5G4::b>* \!'V#\\&!F(;FVm!8a!,T#a%[%#+vUZ![A\ D $NFF{foV#\\&!F(;FVm!8a"4sF%HN c*::!774C(//9DK ~((4::bq>$.bhh(?J  		(	" 	 	 !T7G<H	a q 	.A)-GC1%&	.	A!	q 	6A)-fGC1%&	6 q$**Q-( 	6A)-c1fGC1%&	6  yyA~$**Q-1,),GC1%& 8c#r~~';';C'@ABWL01GGQ	!,--.GGYq\)*OE>rt   c                    | t         u xr* |j                  | j                  k(  xr |j                  d   }|sy|j                  d d \  }}|j
                  dk(  rdn|j                  d   }t        j                  j                  }|dk(  r|j                  }	n|dk(  r|j                  }	n|j                  }	|r|j                  }
n|j                  }
|	|
k(  r||d d  yd}t        ||z  |z        }t        d|      }d}||k  r~t        ||z   |      }|||d	f   }|||d	f   }t        j                  |||j                  d   |j                   d   |	      }|j#                  |
      }t%        |dd
      |d d  |}||k  r~y)NC_CONTIGUOUSFr   r   rP   Ti   r   .)r  rL  )r   r   r   r  r'  rV  r   QImageFormatFormat_Grayscale8Format_RGB888Format_RGBA8888Format_ARGB32r\   r  r^  r  convertToFormatr3   )r
  ainaoutr  
can_handlenrowsncolsnchansr  in_fmtout_fmtnpixels_chunkbatchrow_begrow_endain_view	aout_viewqimgs                     rg   r  r    s    rQcii2883Q		.8QJ99Ra=LE5((a-QSYYq\F\\  F{))	1%%''((&&QM%./E5MEG
E/gou-ww+,#-.	||HeX^^A->APVW##G,#DuF	! E/ rt   c                    t        j                  d      r)t        t        j                  j                  |             }n| }| j                  dd \  }}| j                  d   }t        j                  |||||      }| |_
        |S )z
    Low level function to encapsulate QImage creation differences between bindings.
    "arr" is assumed to be C-contiguous. 
    PyQtNr   r   )r   
startswithr\   r   r   voidptrr'  r  r   r  r_  )r  rr   img_ptrr  rK   bytesPerLiner*  s          rg   ndarray_to_qimager1    st       bffnnS)* 99Ra=DAq;;q>L<<A|S9DDIKrt   c                    t        j                         }d}| j                  dk(  r%t        j                  j
                  j                  }n| j                  dk(  r|| j                  d   dk(  }| j                  d   dk(  r_|du rPt        j                  | j                  dd dz   | j                        }| |ddddddf<   d	|dddddf<   |} d}nt        d
       |d       |r%t        j                  j
                  j                  }n0t        j                  j
                  j                  }nt        d      |r| j                  d      } | j                   d   s/|du r|rdnd}t        d|z         t        j"                  |       } d} |d       |du r|du r| j%                         }  |d       t'        | |      S )a  
    Turn an ARGB array into QImage.
    By default, the data is copied; changes to the array will not
    be reflected in the image. The image will be given a 'data' attribute
    pointing to the array which shares its data to prevent python
    freeing that memory while the image is in use.
    
    ============== ===================================================================
    **Arguments:**
    imgData        Array of data to convert. Must have shape (height, width),
                   (height, width, 3), or (height, width, 4). If transpose is
                   True, then the first two axes are swapped. The array dtype
                   must be ubyte. For 2D arrays, the value is interpreted as 
                   greyscale. For 3D arrays, the order of values in the 3rd
                   axis must be (b, g, r, a). 
    alpha          If the input array is 3D and *alpha* is True, the QImage 
                   returned will have format ARGB32. If False,
                   the format will be RGB32. By default, _alpha_ is True if
                   array.shape[2] == 4.
    copy           If True, the data is copied before converting to QImage.
                   If False, the new QImage points directly to the data in the array.
                   Note that the array must be contiguous for this to work
                   (see numpy.ascontiguousarray).
    transpose      If True (the default), the array x/y axes are transposed before 
                   creating the image. Note that Qt expects the axes to be in 
                   (height, width) order whereas pyqtgraph usually prefers the 
                   opposite.
    ============== ===================================================================    
    Fr   rP   Nr   Tr  r   r@   z>Array has only 3 channels; cannot make QImage without copying.zadd alpha channelz$Image array must have ndim = 2 or 3.r   r   r   r  z (try setting transpose=False)rS   z<Array is not contiguous; cannot make QImage without copying.r  r  )r   ru  rV  r   r  r  r  r'  r   rZ  r   r3  r  Format_RGB32r   rL  r  r  r  r1  )	r  r   r  rL  r  copied	imgFormatd2extras	            rg   r2   r2   >  s   > nnGF||qLL''99			=]]1%*E==q t|XXgmmBQ/$6gmmL$1Qrr6
1Qq5	 `aa#$++99I++88I>??##I.==(5=8A4rEZ[``aa&&w/ t|%,,.FOWi00rt   c                    | j                         }|t        d      | j                         | j                         }}| j	                         }| j                         }||z  dz  }t        j                  d      r|j                  ||z         t        j                  |t        j                        j                  ||f      }|d d d |f   }|dv rt        j                  }|dz  }	n%|dv rt        j                  }|dz  }	nt        d      ||f}
|	d	k7  r|
|	fz   }
|j                  |      j                  |
      }|S )
NzNull QImage not supportedrO   r,  r   )rO          )r   @   r   zUnsupported Image Typer   )bitsr{   heightr   r0  depthr   r-  setsizer   
frombufferr   rz  uint8uint16view)r*  r/  r  rK   bplr?  logical_bplmemoryr   nchanr'  r  s               rg   ndarray_from_qimagerI    s(   iikG455;;=$**,qA



CJJLEe)q.K  	C ]]7"((3;;QHEFA||O$F
	(			122qDEz 
++e

$
$U
+CJrt   c                     t        |       }| j                         }|| j                  j                  k(  rd|d<   |r|j	                         }|r|j                  d      S |S )a_  
    Convert a QImage into numpy array. The image must have format RGB32, ARGB32, or ARGB32_Premultiplied.
    By default, the image is not copied; changes made to the array will appear in the QImage as well (beware: if
    the QImage is collected before the array, there may be trouble).
    The array will have shape (width, height, (b,g,r,a)).
    r@   .rP   r3  )rI  formatr  r4  r  rL  )imgr  rL  r  rr   s        rg   r3   r3     sY     c
"C
**,C
cjj%%%E
hhj}}W%%
rt   c                 >   | j                  t              } | j                  d   dk(  rAt        j                  | j                  dd dz   | j
                        }| |dddf<   d|d	<   |} |j                  t              }t        j                  | j                  dd d
z   t              }| j                         }dD ]A  }| d|f   }||   }||kD  }||   |z
  d|z
  z  |d|f   |<   ||k  }	|||	   z
  |z  |d|f   |	<   C |j                  d      dz  |d	<   |d	   dk\  }d|d	   |   z  }
dD ]<  }|d|f   |   ||   z
  |
z  ||   z   |d|f   |<   |d	   |xx   | d	   |   dz  z  cc<   > t        j                  |dd      j                  t        j                        S )a  
    Given an RGBA image in *data*, convert *color* to be transparent. 
    *data* must be an array (w, h, 3 or 4) of ubyte values and *color* must be 
    an array (3) of ubyte values.
    This is particularly useful for use with images that have a black or white background.
    
    Algorithm is taken from Gimp's color-to-alpha function in plug-ins/common/colortoalpha.c
    Credit:
        /*
        * Color To Alpha plug-in v1.0 by Seth Burgess, sjburges@gimp.org 1999/05/14
        *  with algorithm by clahey
        */
    
    rt  rP   Nr   r  r   .r@   rK  )rP   r   r   r   r  rE  r   r   )rx  rX   r'  r   rZ  r   r   r  r  r  r   )r_  r   r7  r   rf  rj  rL   rG   r  imask
corrections              rg   r4   r4     s    ;;uDzz"~XXdjj!nT)<3rr6
5	LLEHHTZZ^D(6EYY[F 1QK!H1ugkdQh7c!eTA 1U8|q0c!eU1 II1I%,F5M%=CDud++J 8 &s1ud 3E!H <
JeTUhVs1ududtE{404778
 7761c"))"((33rt   c           
         t               }|r|j                  |       nt        }|j                  |      r|f| j                  z  }| j                         }| |z
  }t        | j                        D ]^  }||   }|dk(  rt        |dz        }|j                  | |      }	|j                  |	dz   d|dz  z  z        }
dg| j                  z  }t        |
      ||<   |
j                  |      }
| j                  |   |z   }dt        |      d|j                  z  dz  z  z  }||j                  j!                  |j                  j#                  |||      |j                  j#                  |
||      z  |      z  }t%        d      g| j                  z  }t%        |j                  |   | j                  |   z
  dd      ||<   |t'        |         }a ||z   S )	z
    Drop-in replacement for scipy.ndimage.gaussian_filter.
    
    (note: results are only approximately equal to the output of
     gaussian_filter)
    r   r   r   r   r   r  rE  N)r   r  r   isscalarrV  meanrU  r\   arangeexpro   rz  r'  r[   pifftirfftrfftrJ  r/  )r_  sigmar  r
  baselinefilteredrb  rN   ksizera   kernelkshaper'  r  sls                  rg   r5   r5     s    
B&(		T	"bB	{{5499$yy{HhHDII '"I6 AE
IIufe$A1a4()		![r
' 

2&s1v2553./266<<He"(M(*FE(K)L-/ ( 1 1
 Dk]TYY&x~~b)$**R.8dC2E"I&/'0 hrt   c                 L   d}t        | d      r2| j                  d      r!| }| j                  t        j                        } t        |d      rIt        |d      s|gt        |      z  }t        t        |            D ]  }t        | ||   ||         }  | S |dk  r| S t        | j                  |   |z        }t        | j                        }|||<   |j                  |dz   |       t        d      g| j                  z  }t        d||z        ||<   | t        |         }	t        |      |	_	        |	j                  |dz         }
||
S |j!                         }d||   v r:|dk(  r||   d   dd|   d| ||   d<   n|d	k(  rt        ||   d   |      ||   d<   t#        |
|
      S )zDownsample by averaging points together across axis.
    If multiple axes are specified, runs once per axis.
    If a metaArray is given, then the axis values can be either subsampled
    or downsampled to match.
    Nr$  r
   r   r   r   r	  	subsampler6   )info)r   r$  rD  r   r&  ro   rU  r6   r\   r'  r.  insertrJ  rV  r/  rT  infoCopyr
   )r_  r   rF  xvalsmarj  nPtsrN   ra  d1r7  rd  s               rg   r6   r6     s    
Bl#(Dyy$ tYq)$CIAs4y! 	3AdAaD$q'2D	3Avtzz$!#$DTZZAAdGHHT!VQ
+	"BQQBtH	eBiBQxBH	aB	z	{{}tDz!#'+Dz(';CaC'@$'GT
8$,&'1$t*X2F'JT
8$$''rt   c                     |  }t        j                  t        |             }d||<   t         j                  j	                  ||       t        j
                  |d      }|t        |       k  r||d | |S y )Nrt  r  r   )r   rU  ro   r  
accumulatesearchsorted)rZ   r  r   firsts       rg   _compute_backfill_indicesro  K  sl     9D
))CM
"CCIJJ#3'OOC#Es8}FU
rt   c                 z   | j                   d   }|dk(  rt        j                         S d }|rYt        j                  |       t        j                  |      z  }|j                         s|j                         d   }t        |      }|dk  rt        j                         S d}||z   dz
  |z  }d}||k  rt        |      }	t        |	      }
|| |
d d df<   ||
d d df<   n| |   |
d d df<   ||   |
d d df<   t        j                         }t        |d      r|j                  |       |j                  |	       |S t        j                         }t        |d      r|j                  |       t        j                         }d }t        |      D ]+  }t        ||z  t!        |dz   |z  |            }|j"                  |j$                  z
  }||j'                         k7  rBt        |d      r|j)                  |       n$|j+                  t-        j.                         |       t        |      }|| |   |d d df<   ||   |d d df<   n||   }| |   |d d df<   ||   |d d df<   |t        j                         }|j                  |       |j1                  |       t        |d      r|j3                          *d }. |S )	Nr   r   i'  r   rP   reserveresizeclear)r'  r   r  r   rZ   r:  nonzeroro   create_qpolygonfndarray_from_qpolygonfr   rq  
addPolygon	QPolygonFrU  rJ  r^  stopstartrn  rr  fillr   QPointFconnectPathrs  )ra   rI   finiteCheckr   
finite_idxrZ   	chunksize	numchunks	minchunkspolyr  r  subpolysubpathr   ra  currsizesubarrfivs                      rg   _arrayToQPath_allr  _  s   	
AAv!!##J;;q>BKKN2||~!))+A.JJA1u!!##IY"y0II9"$T*C1IC1I*C1I*C1I!!#4#LLO DtYQooGGY 3y=#s1ui&7";<77RXX%w||~%w)x(V^^-x8'0R5F1a4LR5F1a4LR.CS6F1a4LS6F1a4L?((*G7#!7G$MMOG/0 Krt   c                    | j                   d   }|dk(  rt        j                         S |+t        j                  |       t        j                  |      z  }t        j                         }t        |d      r|j                  |       t        j                  |       d   dz   }t        j                  | |      }t        j                  ||      }t        t        ||            }t        d |D              }	t        |	      t              }
t        d      rj                  }nt        j                          ffd	}|d d D ]O  \  }}t#        |      }|dk  r ||       ||
d |df<   ||
d |df<   |
|dz
     |
|dz
  <   |j%                         Q |dd  D ]A  \  }}t#        |      }|dk  r ||       ||
d |df<   ||
d |df<   |j%                         C |S )	Nr   rq  r   c              3   2   K   | ]  }t        |        y wr   )ro   )ro  chunks     rg   rp  z'_arrayToQPath_finite.<locals>.<genexpr>  s     1U1s   rr  c                 (    j                  ||       S r   )r{  )r   r   r  s     rg   <lambda>z&_arrayToQPath_finite.<locals>.<lambda>  s    Q8J rt   rt  r   )r'  r   r  r   rZ   r   rq  rt  r  r.  r-  r  ru  rv  rr  r   r|  ro   rw  )ra   rI   rZ   r   r  sidxxchunksychunkschunksmaxlenr  subpoly_resizexchunkychunklcr  s                  @rg   _arrayToQPath_finiter    s   	
AAv!!##;;q>BKKN2DtYQ::xi #a'Dhhq$Ghhq$G#gw'(F 111Fv&G#G,F w!  &,^^%5J !"+ 	![7rssAvssAvbd|r!t 	! !+ ![7rssAvssAv ! Krt   c           	         | j                   d   }|dk(  rt        j                         S d}t        |t        j
                        r|d}}d}|dk(  rv|st        | |      S t	        j                  |       t	        j                  |      z  }|t	        j                  |      z
  }|dk(  }|rd}d}n||z  dk  rt        | ||      S d}|}|dk(  rt        | ||      S t        j                         }	t        |	d      r|	j                  |       t        |	d      r.t        d	      r#d}
t        j                  j                  |	|      }nt!        j"                         }
|
j%                  d
|dz  z   dz          |
j'                  dd
t)        j*                  d|             |
j'                  d
|dz  z   dt)        j*                  ddd             t	        j,                  |
g d|d
      }d}|rO|@t	        j                  |       t	        j                  |      z  }t	        j.                  |      }st1        |      }|| |d<   ||d<   n| |   |d<   ||   |d<   |dk(  rd|d   ddd<   d|d   ddd<   n$|dk(  rd|d   dd |dd |d   dd nt3        d      t        |
t         j"                        rt!        j4                  |
      }||	z	   |	S )a  
    Convert an array of x,y coordinates to QPainterPath as efficiently as
    possible. The *connect* argument may be 'all', indicating that each point
    should be connected to the next; 'pairs', indicating that each pair of
    points should be connected, or an array of int32 values (0 or 1) indicating
    connections.
    
    Parameters
    ----------
    x : np.ndarray
        x-values to be plotted of shape (N,)
    y : np.ndarray
        y-values to be plotted, must be same length as `x` of shape (N,)
    connect : {'all', 'pairs', 'finite', (N,) ndarray}, optional
        Argument detailing how to connect the points in the path. `all` will 
        have sequential points being connected.  `pairs` generates lines
        between every other point.  `finite` only connects points that are
        finite.  If an ndarray is passed, containing int32 values of 0 or 1,
        only values with 1 will connect to the previous point.  Def
    finiteCheck : bool, default True
        When false, the check for finite values will be skipped, which can
        improve performance. If nonfinite values are present in `x` or `y`,
        an empty QPainterPath will be generated.
    
    Returns
    -------
    QPainterPath
        QPainterPath object to be drawn
    
    Raises
    ------
    ValueError
        Raised when the connect argument has an invalid value placed within.

    Notes
    -----
    A QPainterPath is generated through one of two ways.  When the connect
    parameter is 'all', a QPolygonF object is created, and
    ``QPainterPath.addPolygon()`` is called.  For other connect parameters
    a ``QDataStream`` object is created and the QDataStream >> QPainterPath
    operator is used to pass the data.  The memory format is as follows

    numVerts(i4)
    0(i4)   x(f8)   y(f8)    <-- 0 means this vertex does not connect
    1(i4)   x(f8)   y(f8)    <-- 1 means this vertex connects to the previous vertex
    ...
    cStart(i4)   fillRule(i4)
    
    see: https://github.com/qt/qtbase/blob/dev/src/gui/painting/qpainterpath.cpp

    All values are big endian--pack using struct.pack('>d') or struct.pack('>i')
    This binary format may change in future versions of Qt
    r   Nr   finiter:  Fg{Gz?rq  enableExperimentalr      rO   z>iz>ii))rG   z>i4)ra   >f8)rI   r  )r   countr  ra   rI   pairsrG   r   r   rt  z;connect argument must be "all", "pairs", "finite", or array)r'  r   r  rU   r   r&  r  rZ   r   r  r   rq  r   r   	internalsget_qpainterpath_element_arrayr   
QByteArrayrr  replacestructpackrA  r:  ro  r{   QDataStream)ra   rI   connectr~  r   connect_arrayrZ   nonfinite_cntall_isfiniter  	backstorer  backfill_idxdss                 rg   r7   r7     s   n 	

AAv!!##M'2::&!('wH('1-- ;;q>BKKN2BFF8,,$)GKQ('1h77 G$M% A{33DtYQtYO4H$I	ll99$B%%'	QrTA&!QD! 45!AbD&!V[[1%=>mmI-WA L{{1~A6H66(+L4X>LCC\?C\?C 'CACA	G	
 C!$Sb)CVWW)V../	*
d
Krt   c                     t         j                  j                  | j                         t	        |       dz  dz  d      }t        j                  |t
        j                        j                  d      S )Nr   rO   Tr   )rt  r   )	r   compatr.  r_  ro   r   rA  r  rz  )polylinevps     rg   rv  rv  r  sO     
		8==?CM!OA,=t	DB==2::.66w??rt   c                     t        j                         }t        |d      r|j                  |        |S |j	                  t        j                         |        |S )Nrr  )r   rx  r   rr  r{  r   r|  )rn  r  s     rg   ru  ru  x  sG     Hx" O 	fnn&-Ort   c                    | j                   |j                   cxk(  r/| j                  d   cxk(  r|j                  d   k(  st        d       t        d      | j                   }t        |      }t	        |      }| |dddf<   ||dddf<   |S )u  
    Utility function to convert two 1D-NumPy arrays representing curve data
    (X-axis, Y-axis data) into a single open polygon (QtGui.PolygonF) object.
    
    Thanks to PythonQwt for making this code available
    
    License/copyright: MIT License © Pierre Raybaut 2020.

    Parameters
    ----------
    x : np.array
        x-axis coordinates for data to be plotted, must have have ndim of 1
    y : np.array
        y-axis coordinates for data to be plotted, must have ndim of 1 and 
        be the same length as x
    
    Returns
    -------
    QPolygonF
        Open QPolygonF object that represents the path looking to be plotted
    
    Raises
    ------
    ValueError
        When xdata or ydata does not meet the required criteria
    r   z&Arguments must be 1D and the same sizeNr   )rn  r'  r{   ru  rv  )ra   rI   rn  r  rG  s        rg   arrayToQPolygonFr    s    8 	
!&&4AGGAJ4!''!*4ABB 	5ABB66D%H#H-FF1a4LF1a4LOrt   c                 T
   |du rd}|rt        j                  | j                  d   dz   | j                  d   dz   f| j                        }| |ddddf<   | d   |dddf<   | d   |dddf<   | dddf   |dddf<   | dddf   |dddf<   |d   |d	<   |d
   |d<   |d   |d<   |d   |d<   |} g ddgddgddgddgddgg dddgddgg dddgddgddgddgddgg g}dd	gd	dgddgddgg}g }| |k  }	t        j                  | j                  D 
cg c]  }
|
dz
  	 c}
t         j
                        }t        j                  dt              }t        dd      t        dd      g}dD ]G  }dD ]@  }|	||   ||   f   |||f<   |d|z  z   }t        j                  ||||f   d|z  z  |d       B I t        |j                  d         D ]  }t        |j                  d         D ]o  }||||f      }t        dt        |      d      D ]H  }|||dz    }g }dD ]$  }|||      d   }|||      d   }| ||d   z   ||d   z   f   }| ||d   z   ||d   z   f   }||z
  ||z
  z  }d|z
  }|d   |z  |d   |z  z   |z   dz   |d   |z  |d   |z  z   |z   dz   f}|rXt        | j                  d   dz
  t        d|d   dz
              t        | j                  d   dz
  t        d|d   dz
              f}|r:|||   dk(  rdndz   |||   dk(  rdndz   ||   dz  f}|j                  ||f       |j                  |       ' |j                  |       K r  |s|S i }|D ]U  \  }} |d   |vrg ||d   <   ||d      j                  || g       | d   |vrg || d   <   || d      j                  | |g       W t        |j                               D ]  }!	 ||!   }"|"D ]}  }#d}
	 |
|#d   d   k(  rnI|#d   d   }
|
|!k(  rn;|#d   d   }$||
   }%|%dd D ]"  }&|&d   d   |$k7  s|#j#                  |&dd        $ ||
= U|#d   d   |#d   d   k(  sm|"j%                             g }|j'                         D ]L  }#t        |#      dk(  r|#d   dd ddd   |#d   z   }#n|#d   }#|j                  |#D cg c]  }|d   	 c}       N |s|S t)        j*                         }|D ]-  }' |j,                  |'d     |'dd D ]  } |j.                  |   / |S c c}
w # t         $ r Y Kw xY wc c}w )a  
    Generate isocurve from 2D data using marching squares algorithm.
    
    ============== =========================================================
    **Arguments:**
    data           2D numpy array of scalar values
    level          The level at which to generate an isosurface
    connected      If False, return a single long list of point pairs
                   If True, return multiple long lists of connected point 
                   locations. (This is slower but better for drawing 
                   continuous lines)
    extendToEdge   If True, extend the curves to reach the exact edges of 
                   the data. 
    path           if True, return a QPainterPath rather than a list of 
                   vertex coordinates. This forces connected=True.
    ============== =========================================================
    
    This function is SLOW; plenty of room for optimization here.
    Tr   r   r   r   rt  Nrs  )r   r   )r   rt  )r   rt  )rt  r   )rt  r   )rt  )rt  rt  rP   r  )r   r   )r   r   r  r  r  r  r   r  r  )r   rZ  r'  r   r   r   objectrJ  addrU  ro   r^  r  r   r.  r)  r   extendpopr	  r   r  r  r  )(r_  level	connectedextendToEdger  r7  	sideTableedgeKeylinesr  ra   r  r  slicesrj  j	vertIndexsidesrM   edgesr  rH   p1p2r?  r@  r  firf   gridKeypointsr   rD   rJ   chainschainrI   connectsconnlines(                                           rg   r8   r8     s   * t|	XXtzz!}Q

1a8

K1R42:1g1ad7Bx2qt81a4j1R47ArE{1R48S'3d84d84uI5	 		
1	
1	
1	
1	
1	
1	
1	
1	
1	
1	
1	
1
!
I( 
				
G E %<D HH4::.aac.bhh?EXXe6*FAbk54=)F S 	SAvay&)34F1Q3K!A#IFF5&1+94%R	SS 5;;q>" "u{{1~& 	"AeAaCj)E1c%j!, "a! &A q*1-B q*1-Ba1gqAw./Ba1gqAw./Brbe,AqB1b2a57*Q.41b2a57*Q.4A $  

1aQ!Q@

1aQ!Q@ !"#E!HaKqQ"?5QR8UV;a\]A^`efg`hij`j"j

Aw<0

1+&. S!5"	"">  F #!Q4vF1Q4LqtQqE"Q4vF1Q4LqtQqE"# &++-  	AYF  	EAb	!$"IaL6"IaL!!9$QK /DAwqzQT!"X./
 1I  Qx{eBil*

)	< E ,u:?!HQRL2&q1E!HEE*qad*+, D T!Wab 	ADKKO	
 K[ /B  		B +s   TT/T%
	T"!T"c                    |j                   dk(  r|j                  }|t        j                  t        j                  df   j	                  t
              }| dt        j                  f   j	                  t
              } t        j                  | |z
        }|j                   dk(  r|j                  d      }t        j                  |d      }g }t        |j                  d         D ]  }||k(  j	                  t
              }t        |||f      }t        |ddd      }t        j                         }	|D ]-  }
 |	j                  |
d	     |
d
d D ]  } |	j                   |   / |j#                  |	        |S )aY  
    Convert an image to a set of QPainterPath curves.
    One curve will be generated for each item in *values*; each curve outlines the area
    of the image that is closer to its value than to any others.
    
    If image is RGB or RGBA, then the shape of values should be (nvals, 3/4)
    The parameter *smooth* is expressed in pixels.
    r   .r   rE  rt  r  T)r  r  r   r   N)rV  Tr   rK  rx  rX   r[   r   argminrU  r'  r5   r8   r   r  r  r  r   )imager	  smoothdifflabelspathsrj  rL   r  r  r  rf   s               rg   r9   r9   	  sT    {{aBJJ

C/077>F#rzz/"))%0E66%,D{{axxQxYYt!$FE4::b>" 
QYu%1vv./C4dC!!# 	 DDKKa!!"X  Q 	 
 	T
 Lrt   c                    t         t        j                  g dt        j                        }g g g dg dg dg dg dg d	g d
g dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg d g d!g d"g d#g d$g d%g d&g d'g d(g d)g d*g d+g d,g d-g d.g d/g d0g d1g d2g d3g d4g d5g d6g d7g d8g d9g d:g d;g d<g d=g d>g d?g d@g dAg dBg dCg dDg dEg dFg dGg dHg dIg dJg dKg dLg dMg dNg dOg dPg dQg dRg dSg dTg dUg dVg dWg dXg dYg dZg d[g d\g d]g d^g d_g d`g dag dbg dcg ddg deg dfg dgg dhg dig djg dkg dlg dmg dng dog dpg dqg drg dsg dtg dug dvg dwg dxg dyg dzg d{g d|g d}g d~g dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg d¢g dâg dĢg dŢg dƢg dǢg dȢg dɢg dʢg dˢg d̢g d͢g d΢g dϢg dТg dѢg dҢg dӢg dԢg dբg d֢g dעg dآg d٢g dڢg dۢg dܢg dݢg dޢg dߢg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg dg d g dg }t        j                  g dg dg dg dg dg dg dg d	g d
g dg dg dgt        j                        }t        j                  |D cg c]  }t	        |      dz   c}t        j
                        }dg}t        dd      D ]  }t        j                  t	        |      |dz  ft        j
                        }	t        j                  ||k(        }
t        j                  |
D cg c]  }||d       c}      |	|
dddf   <   |	j                  t	        |      |df      }	|j                  ||	           ||||fa nt         \  }}}}| j                  d   st        d      | |k  }t        j                  | j                  D cg c]  }|dz
  
 c}t        j
                        }t        j                  dt              }t!        dd      t!        dd      g}dD ]k  }dD ]c  }dD ][  }|||   ||   ||   f   ||||f<   |d|z  |z  z
  d|z  z   d|z  z   }t        j"                  |||||f   d|z  z  |d       ] e m t        j                  |j                  D cg c]  }|dz   
 c}dgz   t        j$                        }||   }t'        |dd       D ]j  \  }}t        d      D cg c](  }t!        ||   |j                  |   ||   dz
  z         * }}||d   |d   |d   |d   fxx   |d|z  z  z  cc<   l |dkD  }t        j                  |      }|ddddf   j)                  t        j*                        }| j                  | j                  d   | j                  d   z  | j                  d   z        }t        j,                  |j                  d         ||dddf   |dddf   |dddf   |dddf   f<   dD ]  }|dddf   |k(  }||ddf   }|t        j                  | j.                  dd       | j0                  z  t        j2                  ddf   z  j5                  d      }||   }||| j.                  |   | j0                  z  z      }|||fxx   ||z
  ||z
  z  z  cc<    ||   }|j5                         } t        j                  | dft        j$                        }!d}"t        j                  |j.                        |j0                  z  }#|j7                         }t        dd      D ]=  }t        j                  ||k(        }$|$j                  d   dk(  r1||$dddf   |$dddf   |$dddf   f   }%||   |%   }&t        j"                  |&dddf   |$ddt        j2                  t        j2                  ddf   |&dddf   d       |&j                  |&j                  d   |z  f|&j                  dd z         }&|&|#t        j2                  t        j2                  ddf   z  j5                  d      }&||&   }'|'j                  d   }(|'|!|"|"|(z    |"|(z  }"@ ||!fS c c}w c c}w c c}w c c}w c c}w (  a  
    Generate isosurface from volumetric data using marching cubes algorithm.
    See Paul Bourke, "Polygonising a Scalar Field"  
    (http://paulbourke.net/geometry/polygonise/)
    
    *data*   3D numpy array of scalar values. Must be contiguous.
    *level*  The level at which to generate an isosurface
    
    Returns an array of vertex coordinates (Nv, 3) and an array of 
    per-face vertex indexes (Nf, 3)    
    N(   r   	    
            	  
    
    	                      	      
          0  9  3   :  6  ?  5  <  <
  5  ?  6	  :  3  9  0                     
  	            `  i  c  j  f   o  e  l  l  e  o  f  j  c	  i
  `            r@               	      
  P  Y  S  Z  V  _  U   \  \  U  _  V  Z
  S  Y  P	                             
  	    rW  rV  rU  rT  rS  rR  rQ  rP  rO  rN  rM  rL  rK  rJ  rI  rH  rG  rF  rE  rD  rC  rB  rA  r@  r?  r>  r=  r<  r;  r:  r9  r8  r7  r6  r5  r4  r3  r2  r1  r0  r/  r.  r@   r-  r,  r+  r*  r)  r(  r'  r&  r%  r$  r#  r"  r!  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r
  r	  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r   )r   rO   rP   )r   r   	   )r   rO   rP   rX  rO   r   )r   r   r   )r   rO   rP   r   r   r   )rX  r   r   r   r   rX  )	r   rO   rP   r   r   rO   r   rX  rO   )rP      r   )r   rY  r   rO   rY  r   )r   rX  r   r   rP   rY  )	r   rY  r   r   rX  rY  rX  rO   rY  )rP   r   r   rY  r   rP   )	r   r   r   r   rO   r   rO   rY  r   )	rP   rX  r   rP   rY  rX  rY  r   rX  )rX  rO   r   r   rO   rY  )r   r"  rO   )r   rP   r   r"  rP   r   )r   r   rX  rO   r   r"  )	r   r   rX  r   r"  r   r"  rP   r   )r   r   r   rO   r   r"  )	rP   r   r"  rP   r   r   r   r   r   )	rX  r   r   rX  r   r   rO   r   r"  )r   r   rX  r   rX  r"  r   r"  rP   r"  rX  r   )rO   r   r"  rP   rY  r   )	rY  r   r"  rY  r   r   r   r   r   )	rX  r   r   rO   r   r"  r   rP   rY  )r   r"  rY  rX  r   rY  rX  rY  r   rX  r   r   )	rP   r   r   rP   rY  r   r"  rO   r   )r   rY  r   r   r   rY  r   r   r   r"  rY  r   )r   r"  rO   rX  r   rY  rX  rY  r   rY  r   rP   )	r   r"  rY  r   rY  rX  rX  rY  r   )rX     r   )rX  rZ  r   r   rO   rP   )r   rZ  r   r   rZ  r   )	rO   rZ  r   rO   rP   rZ  rP   r   rZ  )r   r   r   rX  rZ  r   )	rP   r   rO   r   r   r   r   rX  rZ  )	rZ  r   r   rZ  r   r   r   r   r   )r   r   rZ  rP   r   rZ  rP   rZ  r   rP   r   rO   )rX  rZ  r   r   rP   rY  )	r   rY  r   r   rO   rY  r   rX  rZ  )	r   rZ  r   r   r   rZ  r   rP   rY  )r   r   rZ  r   rZ  rO   r   rO   rY  r   rO   rZ  )	r   rP   rY  r   r   rP   rX  rZ  r   )r   rX  rZ  r   rO   r   rO   r   r   rO   rY  r   )rZ  r   r   rZ  r   rY  rZ  rY  r   rY  r   rP   )	rZ  r   rO   rZ  rO   r   r   rO   rY  )rX  r"  rO   rZ  r"  rX  )	rX  rP   r   rX  rZ  rP   rZ  r"  rP   )	r   r"  rO   r   r   r"  r   rZ  r"  )r   rZ  rP   rP   rZ  r"  )	rX  r"  rO   rX  rZ  r"  r   r   r   )r   r   r   rX  rZ  r   rZ  rP   r   rZ  r"  rP   )rO   r   r   rO   r   rZ  rO   rZ  r"  r   rZ  r   )	r   r   rZ  r   rZ  rP   rP   rZ  r"  )	r"  rX  rZ  r"  rO   rX  rP   rY  r   )rX  rZ  r"  rX  r"  r   rX  r   r   r   r"  rY  )r   rP   rY  r   r   rO   r   r"  rO   r   rZ  r"  )	rY  r   r   rY  r   r"  r"  r   rZ  )rX  rZ  rO   rO   rZ  r"  r   r   rP   r   rP   rY  )rZ  r"  r   rZ  r   rX  r"  rY  r   r   r   r   rY  r   r   )rY  r   r   rY  r   rP   r   rZ  r   rO   r   r"  rZ  r"  r   )rY  r   rZ  r"  rY  rZ  )r   r   rZ  )r   rO   rP   rZ  r   r   )rX  r   r   rZ  r   r   )	r   rO   rP   r   rX  rO   rZ  r   r   )r   r   rZ  r   r   r   )	r   r   rZ  r   r   r   rP   r   rO   )	rX  r   rZ  rX  r   r   r   r   r   )rZ  rX  rO   rZ  rO   r   rZ  r   r   rP   r   rO   )r   rP   rY  r   r   rZ  )	rY  r   rO   rY  r   r   r   r   rZ  )	r   r   rX  r   rP   rY  rZ  r   r   )rZ  r   r   r   rX  r   rX  rY  r   rX  rO   rY  )	r   rP   rY  r   rZ  rP   rZ  r   rP   )r   rO   rY  r   rY  rZ  r   rZ  r   rZ  rY  r   )rP   rY  r   r   rP   r   r   r   rZ  r   rZ  rX  )	r   rZ  rX  r   rX  rY  rY  rX  rO   )rZ  r   r   r   r"  rO   )	r   rP   r   r   r"  rP   r   rZ  r   )	r   rX  r   rZ  r   r   rO   r   r"  )r   r   rZ  r   rX  r"  r   r"  rP   r"  rX  r   )	r   r   r   r   rZ  r   r   r"  rO   )r   r   rZ  rZ  r   r   rP   r   r   rP   r   r"  )rO   r   r"  rX  r   rZ  r   r   rZ  r   r   r   )r"  rP   rX  r"  rX  r   rP   r   rX  rZ  rX  r   r   r   rX  )	rP   rY  r   r"  rO   r   r   r   rZ  )rZ  r   r   r   r"  r   r   r   r   r   r"  rY  )r   r   rX  r   r"  rO   r   rP   rY  rZ  r   r   )rX  r   r   rX  rY  r   rX  r   rY  r"  rY  r   rZ  r   r   )rO   r   r"  rP   rY  rZ  rP   rZ  r   rZ  rY  r   )rZ  r   rY  rZ  rY  r   r   r   rY  r"  rY  r   r   r   rY  )r   rZ  rX  r   r   rZ  r   rP   r   rY  r   rP   rO   r   r"  )r   rZ  rX  r   rX  rY  r   r"  rX  r"  rY  rX  )r   r   rX  r   r   r   )	r   r   r   r   rX  r   r   rO   rP   )	r   r   r   r   r   r   r   r   r   )rO   rP   r   rO   r   r   rO   r   r   r   r   r   )	r   r   rX  r   r   r   r   r   r   )rP   r   rO   r   r   rX  r   r   rX  r   r   r   )r   r   r   r   r   r   )	rO   rP   r   rO   r   r   r   r   r   )	r   r   rX  r   r   r   rY  r   rP   )r   rO   r   r   rO   rY  r   rX  r   r   r   r   )rP   rY  r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   rO   r   r   r   rY  rO   rY  r   )rX  r   r   rX  rP   r   rX  r   rP   rY  r   rP   )rO   rY  r   rO   r   r   rY  r   r   rX  r   r   r   r   r   )	rP   rY  r   rP   r   r   r   r   r   )r   r   rO   rY  r   rO   )	r"  r   r   r"  rO   r   rO   rX  r   )r   r"  rP   r   r   r"  r   rX  r   r   r"  r   )r   r   r"  r   r   r"  r   r"  rO   r   rO   r   )	r   r   r"  r   r"  r   r   r"  rP   )r   r   r   r   r   rO   r   rO   rX  rO   r   r"  )r   r   rX  r   rX  r   r   r"  rX  r   rX  rP   r"  rP   rX  )	r"  rO   r   r"  r   r   r   r   r   )r"  rP   r   r   r"  r   )r   rP   rY  r   r   rO   r   rO   rX  rO   r   r"  )r   r   r"  r   r"  rY  r   rX  r"  r   r"  r   rX  r   r"  )r   rO   r   r   r"  rO   r   r   r"  r   r"  r   r   rP   rY  )rY  r   r   rY  r   r"  r   r   r   r   r"  r   )rO   rX  r   rO   r   r"  rX  r   r   rY  r   rP   r   rP   r   )r   rX  r   rY  r   r"  )r"  rO   r   r"  r   r   rP   rY  r   rY  r   r   )r"  rY  r   )r"  r   rY  )rP   r   rO   rY  r"  r   )r   r   rX  rY  r"  r   )	rO   r   rX  rO   rP   r   rY  r"  r   )r   r   r   r   rY  r"  )	r   r   r   rP   r   rO   r   rY  r"  )	r   rX  r   r   r   rX  r   rY  r"  )r   rY  r"  r   r   rP   r   rO   rP   r   rX  rO   )r"  r   rP   r   r   r"  )	r"  r   rO   r"  r   r   r   r   r   )	r   r"  r   r   rP   r"  r   r   rX  )r   r   r   r   rO   r   r   rX  rO   rO   r"  r   )	r   r"  r   r   r   r"  r   rP   r"  )r   r"  r   r   r"  r   r   rO   r"  r   r   rO   )r   rP   r"  r   r"  r   r   r   rX  r   r   r"  )	r"  r   r   r"  r   rO   rO   r   rX  )r   rO   r   rY  rO   r   )	rP   r   rY  rP   r   r   r   r   r   )	rO   r   rY  rO   r   r   rX  r   r   )rX  r   r   rX  r   rP   rX  rP   r   rY  rP   r   )	r   rO   r   r   rY  rO   r   r   r   )r   r   r   rP   r   rY  r   r   rY  r   r   r   )r   rY  rO   r   r   rY  r   r   rX  r   r   rX  )r   rX  rP   r   rP   r   rX  r   rP   rY  rP   r   r   r   rP   )	rO   r   rP   rO   r   r   r   r   r   )r   r   r   r   r   r   )r   rX  r   r   rP   r   r   r   r   r   rP   rO   )	r   rX  r   r   r   r   r   r   r   )rO   r   rP   rO   r   r   rO   r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   )r   r   rP   r   rP   rO   r   r   rP   r   rP   rX  r   rX  rP   )r   rX  r   r   r   r   )r   rX  rZ  r"  r   rY  )	r   rO   rP   r   rX  rZ  rY  r"  r   )	rZ  r   r   rZ  r   r   r"  r   rY  )rY  r"  r   rO   rP   r   rP   rZ  r   rP   r   rZ  )	rX  rZ  r   r   r   r   r"  r   rY  )r   rY  r"  r   r   r   r   rO   rP   r   rX  rZ  )r"  r   rY  rZ  r   r   r   r   r   r   r   r   )rP   r   rO   rP   rZ  r   rP   r   rZ  r   rZ  r   rY  r"  r   )	r"  r   rP   r"  r   r   rZ  r   rX  )rX  rZ  r   r   rO   r   r   r   r   r   rO   r"  )rP   r   r   rP   r"  r   r   rZ  r   rZ  r   r   )r   r   rO   r   rO   r"  r   r   rO   r   rO   rZ  r   rZ  rO   )rX  rZ  r   r   r   r   r   r"  r   r   rP   r"  )r   r   r   r   r"  r   r   r   r"  rO   r"  r   rX  rZ  r   )r   r   r   r   r   rZ  r   rP   r   r   r   r"  rP   r"  r   )r"  r   r   r"  r   rO   rZ  r   r   r   rO   r   )	r   rX  rZ  r   rY  rX  rY  rO   rX  )rP   r   rY  r   r   rP   r   rZ  r   r   rX  rZ  )r   rY  rO   r   rZ  rY  r   r   rZ  rZ  r   rY  )	r   rY  rP   r   rP   rZ  rZ  rP   r   )r   r   r   rX  rZ  rY  rX  rY  rO   rY  rZ  r   )r   rY  rP   r   r   rY  r   rX  r   rZ  r   rX  r   r   r   )rY  rO   rZ  rY  rZ  r   rO   r   rZ  r   rZ  r   r   r   rZ  )r   rY  rP   r   rP   rZ  r   r   rP   r   rZ  rP   )rZ  rO   rX  rZ  r   rO   rZ  r   r   rP   rO   r   )	rX  rZ  r   rX  r   r   r   r   r   )r   rZ  rO   r   rO   r   rZ  r   rO   rP   rO   r   r   r   rO   )r   rZ  r   r   r   r   )r   rP   r   r   r   r   rP   rO   r   rZ  r   rX  rO   rX  r   )r   r   r   r   r   r   rX  rZ  r   rZ  r   r   )r   rP   rO   rZ  r   r   )r   rZ  r   )rY  rZ  r   r"  rZ  rY  )	rY  rZ  r   rY  r"  rZ  rO   rP   r   )	rZ  rY  r"  rZ  r   rY  r   rX  r   )r   r"  rZ  r   rY  r"  rX  rO   r   rO   rP   r   )	rY  r   r   rY  r"  r   r"  rZ  r   )r   rO   rP   r   r   r"  r   r"  rZ  r"  r   rY  )rX  r"  rZ  rX  r   r"  rX  r   r   r   rY  r"  )r"  rZ  r   r"  r   rY  rZ  rX  r   rP   r   rO   rX  rO   r   )	r   rZ  r   r   rP   rZ  rP   r"  rZ  )rO   r   r   rO   rZ  r   rO   r"  rZ  r   r   rZ  )rX  r   r   rZ  r   rP   rZ  rP   r"  rP   r   r   )rX  rO   r   rX  r   r   rO   r"  r   r   r   rZ  r"  rZ  r   )r   rP   rZ  rP   r"  rZ  )	r   rO   r"  r   r"  r   r   r"  rZ  )	rX  r   rP   rX  rP   rZ  rZ  rP   r"  )rX  rO   r"  rZ  rX  r"  )	rZ  rO   r   rZ  r   rO   r   rY  rO   )rZ  r   r   rZ  rY  r   rZ  r   rY  rY  rP   r   )r   r   rX  rO   r   r   rO   r   rY  r   r   rZ  )r   rY  r   r   r   rZ  rY  rP   r   rX  r   r   rP   r   r   )r   rZ  r   r   rO   rZ  r   rY  rO   r   rZ  rO   )r   r   rY  r   rY  rP   r   rZ  rY  r   rY  r   rZ  r   rY  )r   r   rZ  r   rZ  rX  r   rY  rZ  r   rZ  rO   rY  rO   rZ  )rX  r   rZ  r   rY  rP   )r   rZ  r   rP   rZ  r   rP   r   rZ  rP   rO   r   )	rZ  r   r   rZ  r   r   r   r   r   )rP   r   r   rP   rZ  r   rP   rO   rZ  r   rZ  rO   r   r   rX  )rZ  r   r   rZ  r   r   r   rX  r   rX  r   r   )	rO   r   rZ  rO   rZ  rP   rP   rZ  r   )r   r   rZ  r   r   rZ  )rO   r   rZ  rO   rZ  rP   rX  r   rZ  r   rP   rZ  )rX  r   rZ  )	r   rY  r"  r   rX  rY  rX  r   rY  )r   rO   rP   r   rX  r"  rX  rY  r"  rX  r   rY  )r   r   rY  r   rY  r   r   r   r   r"  r   rY  )rP   r   r   rP   r   rO   r   r   r   r"  r   rY  r   rY  r   )r   rY  r"  rX  rY  r   rX  r   rY  rX  r   r   )rX  r"  r   rX  rY  r"  rX  r   rY  r   rY  r   r   rO   rP   )	rY  r"  r   rY  r   r   r   r   r   )rY  r"  r   rY  r   r   rO   rP   r   rP   r   r   )r   rX  r   r   r"  rX  r   rP   r"  r"  r   rX  )rX  r   r"  rX  r"  r   r   r   r"  rO   r"  r   r   r   r"  )rP   r"  r   rP   r   r   r"  r   r   r   r   r   r   r   r   )r   r   r   rO   r"  r   )	r   rX  r   r   r   r"  r"  r   rP   )r   rX  r   r   r   r"  r   rO   r   rO   r"  r   )r   r   rP   r"  r   rP   )r   rO   r"  )rX  r   rO   r   rY  rO   )	rP   r   rX  rP   rX  rY  rY  rX  r   )	r   r   r   r   r   rO   rO   r   rY  )rP   r   r   rY  rP   r   )	r   r   rY  r   rY  rX  rX  rY  rO   )rP   r   rX  rP   rX  rY  r   r   rX  r   rY  rX  )r   r   rY  rO   r   rY  )rP   r   rY  )	r   rP   rO   r   rO   r   r   rO   rX  )rX  r   r   r   rX  r   )r   rP   rO   r   rO   r   r   r   rO   r   r   rO   )r   r   r   )r   rP   rO   rX  r   rO   )r   rX  r   )r   rP   rO   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   rP   r   r   r   r  z+isosurface input data must be c-contiguous.)r   r   r   rt  rs  r   r   r  r     rO  rE  .)IsosurfaceDataCacher   r   rC  ro   r   rU  r   argwhererz  r   r  r   r'  rZ  r  rJ  r  uint32r   rx  r  rU  r  r  rK  r   flatten))r_  r  	edgeTabletriTable
edgeShiftsr  nTableFacesfaceShiftTablesrj  
faceTableIfaceTableIndsr  r  ra   r  r  r  rJ   r  cutEdgesr  shiftrH   
vertexIndsvertexesdataFlatvimviviFlatr?  r@  nFacestotFacesfacesptrcscellscellIndsvertsvertIndsnvs)                                            rg   r:   r:   	  sI   ( "
 HH !B YYC! 	NA
A
A
 A
 	A

 A
  A
  A
 *A
 A
 !A
  A
 +A
 "A
 ,A
 +A
  "!A
" #A
$ %A
& 'A
( ()A
*  +A
, )-A
. )/A
0 21A
2  3A
4 *5A
6 )7A
8 49A
: +;A
< 5=A
> 5?A
@ ,AA
B CA
D EA
F GA
H (IA
J  KA
L )MA
N )OA
P 2QA
R  SA
T *UA
V )WA
X 2YA
Z +[A
\ 4]A
^ 5_A
` +aA
b cA
d (eA
f (gA
h iA
j )kA
l 2mA
n 2oA
p )qA
r )sA
t 2uA
v 2wA
x *yA
z 4{A
| >}A
~ >A
@ "AA
B CA
D  EA
F  GA
H )IA
J KA
L (MA
N (OA
P 1QA
R !SA
T +UA
V *WA
X 4YA
Z )[A
\ 4]A
^ 2_A
` *aA
b  cA
d )eA
f )gA
h 2iA
j (kA
l 1mA
n 1oA
p :qA
r *sA
t 3uA
v 3wA
x >yA
z 3{A
| ?}A
~ ;A
@ 3AA
B !CA
D *EA
F *GA
H 2IA
J (KA
L 1MA
N OA
P (QA
R +SA
T 4UA
V 3WA
X =YA
Z 2[A
\ <]A
^ )_A
`  aA
b +cA
d 4eA
f 3gA
h *iA
j 1kA
l :mA
n (oA
p qA
r 4sA
t =uA
v =wA
x 4yA
z ;{A
|  }A
~ 3A
@ AA
B CA
D  EA
F  GA
H )IA
J !KA
L *MA
N *OA
P 5QA
R SA
T (UA
V (WA
X 1YA
Z *[A
\ 3]A
^ 4_A
` +aA
b  cA
d )eA
f )gA
h 2iA
j *kA
l 4mA
n 4oA
p =qA
r (sA
t uA
v 1wA
x (yA
z 2{A
| *}A
~ <A
@ !AA
B  CA
D )EA
F )GA
H 2IA
J *KA
L 3MA
N 4OA
P <QA
R (SA
T 1UA
V 1WA
X :YA
Z 2[A
\ ;]A
^ ?_A
` 5aA
b *cA
d 2eA
f 4gA
h )iA
j 5kA
l =mA
n =oA
p 4qA
r 1sA
t (uA
v :wA
x yA
z ;{A
| 3}A
~  A
@ AA
B "CA
D +EA
F +GA
H 4IA
J *KA
L 2MA
N 2OA
P ;QA
R )SA
T 2UA
V 3WA
X ;YA
Z [A
\ (]A
^ (_A
` aA
b +cA
d 5eA
f 5gA
h >iA
j 2kA
l ?mA
n <oA
p  qA
r 2sA
t )uA
v <wA
x 2yA
z ({A
| }A
~ 1A
@ AA
B ,CA
D 4EA
F 5GA
H >IA
J 4KA
L =MA
N *OA
P 3QA
R 2SA
T <UA
V ?WA
X  YA
Z ([A
\ 1]A
^ _A
` aA
b "cA
d +eA
f ,gA
h "iA
j +kA
l 3mA
n !oA
p qA
r *sA
t  uA
v 3wA
x yA
z {A
| }A
~ A
@ AA
D XX
 
 hh(;QAq;288L&q 	;A3x=!A#"6bhhGJKKq(89M-/XX}6]!x!~6]-^J}QqS)*#++S]Aq,ABJ"":j#9:	;  /
I{S>Q;Y ::n%EFF %<D HH4::.aac.bhh?EXXgV,FAbk54=)F Y 	YA Y $VAYq	6!9%D Eq1u!AI!Oac1	ufQqUmal:xXY	YY xxekk212A36biiHHeEj"o. L5JOPQ(SQ%a!2E!HQJ!?@SSF1Ivay%(:;uq!t|K;L
 	1AQJ!BQB$&&rzz2H||DJJqM$**Q-7

1EFH TVS\S\]g]m]mno]pSqHZ!_j1oz!A#
1Q3OP 01o"RaR bq!12dmmCRZZPQ\RRWW]^W_fft||A==>QE"HB//0. Fzz|HHHh]"))4E
C
 
(""	#X%6%6	6B!H 1QZ  FaK(;;q>QqsU1Q3Zqs;<  "8,
uS!V}eAbjjA$=>E#bqb&M[cdu{{1~a/1%++ab/AB BJJ

A566;;;CE?^^A$c#b&r	36 U?s  < 7^0 / 3 Ts   k7k
kk-kc                    t        j                  | j                         | j                         | j	                         | j                         | j                         | j                         | j                         | j                         | j                         g	      }d|_        t         j                  j                  |      }t        j                  |j!                         j#                          S )N)rP   rP   )r   r   r  r  r  r  r  r  r  r  r  r'  r  pinvr   r  raveltolist)rh  r  rz  s      rg   _pinv_fallbackr}    s    
((BFFHbffhFFHbffhFFHbffh2 3C CI99>>#DTZZ\00233rt   c                     	 | j                         }d|z  }| j                         }||z  }|S # t        $ r t        |       cY S w xY w)aC  Return a QTransform that is the inverse of *tr*.
    A pseudo-inverse is returned if tr is not invertible.
    
    Note that this function is preferred over QTransform.inverted() due to
    bugs in that method. (specifically, Qt has floating-point precision issues
    when determining whether a matrix is invertible)
    r   )determinantadjointZeroDivisionErrorr}  )rh  detdetrinvs       rg   r;   r;     sO    "nnSyjjlt
 "b!!"s   +. AAc                 T    |dk(  rt        | |||      S |dk(  rt        | |||      S y)aJ  Return an array of position values needed to make beeswarm or column scatter plots.
    
    Used for examining the distribution of values in an array.
    
    Given an array of x-values, construct an array of y-values such that an x,y scatter-plot
    will not have overlapping points (it will look similar to a histogram).
    exact)spacingshufflebidir	histogramN)_pseudoScatterExact_pseudoScatterHistogram)r_  r  r  r  methods        rg   r<   r<     s=     "4'QVWW	;	&tWgUZ[[ 
rt   c                    t        j                  t        |             }|rt         j                  j	                  |       | |   } |'dt        j
                  |       z  t        |       dz  z  }t        j                  t        |             }| j                         }| j                         }t        ||z
  |z        dz   }t        j                  |||      }	|	d   |	d   z
  }
| |	d   z
  |
z  j                  t              }i }t        |      D ]$  \  }}|j                  |d      dz   }|||<   |||<   & |du r3t        |      D ]%  }|||k(  xx   |j                  |d      dz  z  cc<   ' |t        j                  |         S )zWorks by binning points into a histogram and spreading them out to fill the bin.
    
    Faster method, but can produce blocky results.
           @r  r   r   rt  T)r   rU  ro   randomr  stdrZ  r^  r  r\   linspacerx  r   r   rU  argsort)r_  r  r  r  rg  yvalsdmindmaxnbinsbinsr  dbins	binCountsrj  r  rG   s                   rg   r  r    sp   
 99SYD
		$:DRVVD\/#d)S.0HHSYE88:D88:Ddg%&*E;;tT5)D	a47	BT!Wn"**3/EI !MM!R 1$	!a
 }u 	9A%(Oy}}Q2S88O	9 D!""rt   c                 $   t        j                  t        |             }|rt         j                  j	                  |       | |   } |'dt        j
                  |       z  t        |       dz  z  }|dz  }t        j                  t        |             }t        |       dk(  r|S d|d<   t        dt        |             D ];  }| |   }| d| }	|d| }
d}|	|z
  dz  }||k  }|j                         dkD  r|rddg}ndg}g }|D ]  }d}||   }||z
  dz  }t        j                  dt        |      f      }|
|   |z
  |d<   |
|   |z   |d<   	 |dkD  r	|d   |k\  }n|d   |k  }|dd|f   }|d   |k  |d   |kD  z  }|j                         dk(  rn5|dkD  r|dd|f   j                         }n|dd|f   j                         }y|j                  |        |r|d    |d   k  r|d   n|d   }n|d   }|||<   > |t        j                  |         S )zWorks by stacking points up one at a time, searching for the lowest position available at each point.
    
    This method produces nice, smooth results but can be prohibitively slow for large datasets.
    Nr  r  r   r   r   rt  )r   rU  ro   r  r  r  rZ  rU  r   r  r^  r   r  )r_  r  r  r  rg  s2r  rj  ra   x0y0rI   r  xmaskdirsyopts	directiondx2dylimitsr  limits2s                         rg   r  r    sW   
 99SYD
		$:DRVVD\/#d)S.0	!BHHSYE
4yA~E!H1SY -G"1X2AYdQYR99;?AwsE!  	i3h_1SW+.uINq	uINq	 1}%ayA~%ayA~$QtVnG $AJNwqzA~>DxxzQ 1}#AdFO//1#AdFO//1# $ Q3 4 !&q	E!H 4E!H%(!Ha[-^ D!""rt   c                    | j                         } t        | j                               D ]  \  }}|D ]  }|| vsg | |<     |It               }| j	                         D ]  }|t        |      z  } t        | j                               |z
  }|t               }g }g }	|D ]f  }
|
|v rt        d||
gz         |
|v r|j                  |
       |	j                  t        | | |
   |||
gz   |dz                |	j                  |
       h |	S )u  Topological sort. Arguments are:
      deps    dictionary describing dependencies where a:[b,c] means "a depends on b and c"
      nodes   optional, specifies list of starting nodes (these should be the nodes 
              which are not depended on by any other nodes). Other candidate starting
              nodes will be ignored.
              
    Example::

        # Sort the following graph:
        # 
        #   B ──┬─────> C <── D
        #       │       │       
        #   E <─┴─> A <─┘
        #     
        deps = {'a': ['b', 'c'], 'c': ['b', 'd'], 'e': ['b']}
        toposort(deps)
         => ['b', 'd', 'c', 'a', 'e']
    zCyclic dependency detectedr   )r?  )r  r.  r*  r(  r	  r)  r3  r  r  r=   r   )depsnodesseenstackr?  rJ   r   remdepsortedr   s              rg   r=   r=   8  s    ( 99;DDJJL! ! 	A}Q	
 }e;;= 	C3s8OC	DIIK 3&|uF :8%1#+FF9xd1gtUA3YeAgNOa Mrt   c                     	 	 | j                  |      }|d}|ryt        j                  |      }|y2# t        t        f$ r d}Y /w xY w)a  Disconnect a Qt signal from a slot.

    This method augments Qt's Signal.disconnect():

      * Return bool indicating whether disconnection was successful, rather than
        raising an exception
      * Attempt to disconnect prior versions of the slot when using pg.reload
    TF)r>   r   RuntimeErrorr	   getPreviousVersion)signalslotsuccesss      rg   r>   r>   g  sf     	''-G ((.< 
 <( 	G	s   4 AAc                   "    e Zd ZdZd Zd Zd Zy)r?   zClass used to temporarily block a Qt signal connection::

        with SignalBlock(signal, slot):
            # do something that emits a signal; it will
            # not be delivered to slot
    c                      || _         || _        y r   )r  r  )r   r  r  s      rg   r   zSignalBlock.__init__  s    	rt   c                 P    t        | j                  | j                        | _        | S r   )r>   r  r  	reconnectr   s    rg   r2  zSignalBlock.__enter__  s    #DKK;rt   c                 h    | j                   r&| j                  j                  | j                         y y r   )r  r  r  r  r   s     rg   r5  zSignalBlock.__exit__  s$    >>KK		* rt   N)r   r   r   __doc__r   r2  r5  r   rt   rg   r?   r?     s    +rt   r?   )}:T)rP   rS   TNr  T)r   r   r   )r   )r   )rX  r   r@   rA   ih  r   r@   r@   )r  Nr  r  rP   r   )r   F)r   r   )Fr   )NN)NNNFTN)NTT)FT)r   rc  )r:  T)FFF)r  )NTFr  )NTF)NNNr   )qr  
__future__r   rV   rY   rer  r+  r0  collectionsr   r  r   rS   r   r   r   r	   	metaarrayr
   r   r   r   util.cupy_helperr   util.numba_helperr   __all__r   r   r_   r`   r   rU  ro   r   compileFLOAT_REGEX	INT_REGEXr   r   r   rX   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r/  rG  r\   r  r  r  r  r.   r/   r0   r1   r  r1  r2   rI  r3   r4   r5   r6   ro  r  r  r7   rv  ru  r  r8   r9   r\  r:   r}  r;   r<   r  r  r=   r>   r  r?   )rj  s   0rg   <module>r     s       	  
  #  0 0   % % % 0>0 
a#c	"	aAc	"	c!Ac	"	aC	$	c!C	$	c#a	$	a!C	 	c#c#	&	c#c#	&	c#c#	&	c#c#	&
 #' uSEU?VW![^ac1W5WX  C bjj~  BM  M  Pi  i  jBJJ@;NQffg	 FE< ! 4Un {4 
 
	DELL 	DDN(*7t7 bhh !  " 
 bhh !  " 
 bhh13C5J$L!;F&
2,6_GD:Yx:CL ^FWB8z2.?
<  	S"..&&s+BQ/	01W<
 J1h1Qh72#|~)X>M1`#L*+4Z&R)(X(DN<~KZ@$zslF  JZ4"$\!#HB#L,^2+& +}a Xs   K?