
    U>                     ~    d Z ddlZddlZddlZddZd Zd Zd ZddZ	dd	Z
d
 ZddZddZd Zd ZddZddZdS )z6
util
====

This modules provides various utilities.

    Nc                      ddl m} t          |d          r3 fd}|||d<    |j        ||dd         fdi|}|j        |j        fS t          j        j         fd}|||d<    |j	        ||fi |S )	a  Allows leastsq to take bounds if minimize function is missing.
    
    Args:
        errfunc0 (func): Function that should be used to compute errors. It 
            should take an array of parameters as its first argument.
        x0 (list): Initial guess at parameter values.
        args (Optional[list]): Additional arguments that should be passed to 
            the provided error function. (default = None)
        bounds (Optional[list]): (min,max) pairs placing bounds on what values 
            are allowed for each parameter. (default = None)
        **exkw: Additional keywords arguments are passed to either 
            `scipy.optimize.minimize` or `scipy.optimize.leastsq`.

    Returns:
        list: Best fit parameters.
        int: Error code for the fit.

    r   )optimizeminimizec                 6    t           | g|R  dz            S )N   )sum)xiargserrfunc0s     J/var/www/html/ai-engine/env/lib/python3.11/site-packages/tesseract/util.pyerrfunczmyleastsq.<locals>.errfunc&   s(    xx)5)))1,---    Nargsboundsc                    d k    r{t          t          |                     D ]^}|         d         d k    r| |         |         d         k     rc S |         d         d k    r| |         |         d         k    rc S _ | g|R  S )Nr      )rangelen)r	   r
   idxr   r   lress      r   r   zmyleastsq.<locals>.errfunc-   s    t|| Q== S SCc{1~t++#vc{1~0E0Ed{{{c{1~t++#vc{1~0E0Ed{{{8A%u%%%%r   )
scipyr   hasattrr   r	   successsys
float_infomaxleastsq)	r   x0r   r   exkwr   r   resr   s	   `  `    @r   	myleastsqr!      s    & x
## 3	. 	. 	. 	. 	.DT&\h111CCVCdCCuS[  ~!	& 	& 	& 	& 	& 	& 	& DT&\x22T222r   c                     t          j        | dddf         dz  | dddf         dz  z   | dddf         dz  z             S )zCalculates radius from position.

    Args:
        pos (np.ndarray): (N,3) Positions.

    Returns:
        r (np.ndarray): (N,) Radii.

    Nr   r   r   npsqrt)poss    r   pos2radr'   8   sN     73qqqs8Q;QQQqS1,s111Q3x{:;;;r   c                 ,    dt           j        z  | dz  z  S )zReturns spherical volume for provided radii.
    
    Args:
        r (np.ndarray): (N,) Radii.

    Returns:
        vol (np.ndarray): (N,) Volumes.

    gUUUUUU?      @r$   pi)rs    r   sphvolr-   C   s     25=!R%  r   c                 2    d| z  dt           j        z  z  dz  S )zReturns spherical radii for provided volumes.

    Args:
        vol (np.ndarray): (N,) Volumes.

    Returns:
        r (np.ndarray): (N,) Radii.

    r)   g      @gUUUUUU?r*   )vols    r   sphradr0   N   s     sFBruH''r         ?c                 >    |d}t          j        ||z  | z            S )a6  Returns the circular velocity.

    Args:
        r (np.ndarray): (N,) Radii.
        menc (np.ndarray): (N,) Mass enclosed at each radius.
        G (Optional[float]): Gravitational constant in correct units. 
            (default = 1)

    Returns:
        vcirc (np.ndarray): (N,) Circular velocities.

    Nr1   r#   )r,   mencGs      r   
calc_vcircr5   Y   s%     	yb!71T6!8r   c                     |It          j        |          }t          j        |          }t          j        | |                   |         }nt          j        |           }|S )a  Calculates the total mass enclosed by each particle.

    Args:
        m (np.ndarray): (N,) Masses of particles.
        sortby (Optional[np.ndarray]): Quantity that will be used to sort 
            masses before summing. (The enclosed mass will be returned in the 
            original particle order). If not provided, masses are summed in 
            their current order.

    Returns:
        menc (np.ndarray): (N,) Mass enclosed.

    )r$   argsortcumsum)msortbyidxsortidxsort_revr3   s        r   	calc_mencr=   h   sV     *V$$j))y7$$[1 y||Kr   c                 b    ||k     }| |                                          t          |          z  S )a  Returns the density enclosed within rmax.

    Args:
        mass (np.ndarray): (N,) Masses of particles.
        r (np.ndarray): (N,) Radii.
        rmax (float): Radius which density is computed within.

    Returns:
        float: Average density enclosed within rmax.

    )r   r-   )massr,   rmaxr   s       r   calc_rhoencrA      s*     T6C9==??6$<<''r   F      ?c                 j   t          |t          j                  rt          |          t          |           k    rRt	          d                    t          |                    d                    t          |                     z             t          j        |          }nlt          |t                    r5|rt          dt          |                     }n7t          j        |           }n"t          d                    |                    t          t          j        | |                             }t          |t          j                  rt          |          t          |           k    rRt	          d                    t          |                    d                    t          |                     z             ||z  d|z
  |t          j        |                   z  z   }|r t          j        |          }||         }||fS |S |r||fS |dk    r|S t          j        |          }||         S )a  Calculate particle radii from volume information.

    Volumes are sorted then cummulatively summed to get enclosed volume at each 
    particle. Radii are then calculated by assumming that each enclosed volume 
    is a sphere. Returned radii are in the same particle order as the input 
    volumes.

    Args:
        vol (np.ndarray): (N,) Volumes corresponding to each particle
        sortby (Optional[np.ndarray]): (N,) Array to sort volumes by before 
            calculating radii. If not provided, vol is used. If set to True, 
            volumes are assumed to be already sorted.
        outsort (Optional[bool]): If True, the array for sorting the particles 
            is also output and the returned radii are already sorted.
        weightby (Optional[np.ndarray]): (N,) Values to weight volumes by 
            after calculating radii. Sorting occurs before weighting. This is 
            useful if you would like to weight by the real radius or another 
            measure of radius. The returned radii are then the weighted
            arithmetic mean of the volume based radii (rvol) and the weightby 
            array (i.e. weight*weightby + rvol*(1-weightby)) The resulting 
            array is again sorted if outsort is True. (default = False)
        weight (Optional[float]): Value used to weight the weightby array by. 
            Only used if weightby is not False. (default = 0.5)

    Returns:
        r (np.ndarray): (N,) Radii.

    Raises:
        Exception: If the `sortby` and `vol` arrays are not the same length.
        TypeError: If the `sortby` array is not an array or bool.
        Exception: If the `weightby` and `vol` arrays are not the same length.

    z(The sortby array (len={}) must have the z)same length as the volume array (len={}).r   zInvalid sortby value: {}z*The weightby array (len={}) must have the r1   T)
isinstancer$   ndarrayr   	Exceptionformatr7   boolslice	TypeErrorr0   r8   )r/   r:   outsortweightbyweightr   radidxrevs           r   vol2radrP      s   F &$$ Cv;;C  FMMcRXkkZZGNNsSVxxXXY Z Z Zj  	F4	 	  C 	"#c((##CC*S//CC299&AABBB
3s8$$
%
%C(2:&& 
x==#c((""HOOPST\P]P]^^GNNsSVxxXXY Z Z ZXoFC
3,@ @@ 	*S//Cc(Cs7NJ 3wT>>JZ__Fv;r   c                     d}|dk    r||z  }| dddfxx         |z  cc<   |dk    r||z  }| dddfxx         |z  cc<   | |dz  z  } | S )a  Squeezes 3D positions along y and z axes while preserving volume.

    Args:
        pos (np.ndarray): (N,3) Positions.
        yfact (Optional[float]): Factor that y direction is squeezed by. 
            (0 < yfact < 1)
        zfact (Optional[float]): Factor that z direction is squeezed by. 
            (0 < zfact < 1)

    Returns:
        pos (np.ndarray): (N,3) Transformed positions.

    r1   r   Nr   r   gUUUUUUտ )r&   yfactzfactsqufacts       r   squeeze_constvolrW      s{     GqyyAAAaC%qyyAAAaC%'F
CJr   c                 Z    d}|}t          j        |dz  | |dz  |dz  z
  z  z
            }|S )a:  Return y and z squeeze factors for given triaxiality and ellipticity.

    Args:
        t (float): triaxiality defined as (c**2 - b**2)/(c**2 - a**2) where 
            a > b > c.
        e (float): Overall ellipticity defined as c/a.

    Returns:
        b (float): Factor to squeeze intermediate axis by.

    r1   r   r#   )teacbs        r   triax2squeezer^      s;     	A	A
1q!Q$q!t)}$%%AHr   c                    t          | t                    r| }nt          | t                    r$t          |                               dd          }nt          | t
                    r$t          |                               dd          }n\t          | t                    r8t          |                               dd                              dd          }nt          |           }|S )zWrites values to a string.

    Args:
        val (any): Any object that should be represented by a string.

    Returns:
        valstr (str): String representation of `val`.

    z, ,z: :)rD   strtuplereprreplacelistdict)valvalstrs     r   val2strrj     s     
C		 s	C		 tCyy'8'8c'B'B	C		 tCyy'8'8c'B'B	C		 tCyy'8'8c'B'B'J'J4PS'T'Tc&Mr   c                 >   |                                  }t          |t                    rt          |          }t          |t                    s5t	          |          dk    rd}n|                    d          r.|                    d          r|                     d          }d}n|                                dk    rd}n|                    d          r+|                    d          	                                rd}n|	                                s&|d         dv rD|d	d
         	                                r(t          |          t          |          k    rd}n!d}n|                    d          r-|                    d          r|                     d          }d}n|                                dk    rd}n|                     d                                          dv rd}n|                    d          r&|                    d          rd| v rd}ncd| v rd}n\d}nY|                    d          r|                    d          rd}n,|                    d          r|                    d          rd}t          |t                    r8|                                }|dk    sd|v r|                    d          r,|                    d          r|                     d          }n$|                    d          r,|                    d          r|                     d          }n|}n|dk    sd|v rt          |          }n|dk    sd |v rt          |          }n|d!k    sd|v r2t          t          |                    dd"                              }nm|d#k    sd|v r2t          t          |                    dd"                              }n1|d$k    sd|v r%t          |                    d%d"                    }n|d&k    sd|v rd
}n|d'k    sd|v r|d(|                     d                                          v rd)}nd*|                     d                                          v rd+}nt          d,                    |                     d|v rW|d	d-                             d          }g }|D ]$}|                    t'          |                     %t)          |          }nd|v rG|d	d-                             d          }g }|D ]$}|                    t'          |                     %nd|v rx|d	d-                             d          }i }i }g }|D ]R}d.|v r3|                    d.          \  }}	|	||<   |                    |           9||d-         xx         d|z   z  cc<   SnK	 d|v r$t          |                    d%d"                    }nt          |          }n# t          $ r |}Y nw xY w|S )/a  Recovers variables from a string.

    Args:
        valstr (str): String to converted into an object.
        dtype (type): Type or string specifying type of the object `valstr`
            should be converted to. If not provided, we try to infer the type
            from the format of the string. (default = None)
    
    Returns:
        val (any): Object recreated from `valstr`.

    Raises:
        ValueError: If the data type is boolean, but 'true' or 'false' is not 
            in `valstr`.

    r   rb   "nanfloatLlong)-+r   Nint'none.)truefalserH   ()r`   rc   jcomplex[]rf   {}rg   sfddoublei lr\    nr]   rw   Trx   Fz%Unrecognised string for bool type: {}rQ   ra   )striprD   typerb   r   
startswithendswithlowerrstripisdigitrs   rp   rn   re   r|   
ValueErrorrG   splitappendstr2valrc   )
ri   dtypevalstr_striprh   vallistivalstrval0key0ikeyivals
             r   r   r     s   " L%1s5zzueC   |au$$S)) 	l.C.CC.H.H 	%++C00LEE!!U**'EE""3'' 	L,?,?,D,D,L,L,N,N 	EE!!## 	Q9(D(DVWVXVXIYIaIaIcIc(D<  D$6$666e>D$$S)) 	l.C.CC.H.H 	%++C00LEE!!V++Vuu$$**,,0@@@%%$$S)) 	l.C.CC.H.H 	f}}Geei%%$$S)) 	l.C.CC.H.H 	EE$$S)) 	l.C.CC.H.H 	E% 6kkmmCZZ5E>>((-- #,2G2G2L2L # &&s++((-- #,2G2G2L2L # &&s++"##CZZ7--53F3FssCZZ8--53F3FssCZZ5--E,..s2667788CCCZZ6--U<//B778899CCCZZ9--,,S4455CCCZZ6--4ssCZZ6--L..s3399;;;;SSL..s3399;;;;SS !H!O!OPV!W!WXXX 2&,,S11GC" - -

77++,,,,c

CCu__ 2&,,S11GC" - -

77++,,,,-u__ 2&,,S11GC"TBt" 0 0'>> 'c 2 2ID#DJKK%%%%bNNNCK/NNNN		l""L00R8899 ,'' 	 	 	CCC	 Js   7X XXpr      Tc                    ddl }ddlm} |d                    |          }|rt	          | t
          t          f          sd|dz
   z  }| dk    rt          |           } nht          |           dk    r#t          |           |k     rt          |           } n2t          | t          |           z            |k     rt          |           } t	          | t
          t          f          rd}d|z   d	z                       |           }	|rd
|	v rd|	v sd|	v r_d|	v r|	                    d          \  }
}d|	v r|	                    d          \  }
}d|	v r"t          d                    |	                    n|
                    |	          }
d}|
                    d           |
                    d
           |
|z   }	d}d}||z   } |||          }|	                    ||          S )a*  Convert number to string, replacing punctuation.

    Args:
        numval (float,int): Numeric value to be converted.
        formstr (Optional[str]): Format string used for the conversion. If not 
            provided, one is generated based on `nsig`.
        decrep (Optional[str]): String that '.'s are replaced with. 
            (default = 'p')
        negrep (Optional[str]): String that '-'s are replaced with. 
            (default = 'n')
        nsig (Optional[int]): Number of significan digits. (default = 3)
        trimzero (Optional[bool]): If true, remove trailing zeros in decimal. 
            (default = True)

    Returns:
        str: String created from the number.

    Raises:
        Exception: If both 'e' and 'E' are in the generated string and
            `trimzero` is True.

    r   N)	maketransz.{}gg      $@r   r   z{:r   rv   rZ   Ez"Both e and E are in the string: {}r   0z+ z.-)copystringr   rG   rD   rs   rp   absr   rF   deepcopyr   	translate)numvalformstrdecrepnegrepnsigtrimzeror   r   precvaldecstrdecbasdecexprtabitabftabtrantabs                   r   num2strr     s   . KKK      d 3 3 
'
63t*55 
'Qi Q;;v;;FF6{{av;;((v;;FvF+,,w66v;;F&#d$$1cg'M#%%f--F C6MM&==C6MMf}}FLL,=,=mfVf}}FLL,=,=mfVf}} D K KF S STTT % ==((FFccf}	D	D	DId4  GGD)))r   )NN)r1   )N)FFFrB   )rQ   rQ   )Nr   r   r   T)__doc__osnumpyr$   r   r!   r'   r-   r0   r5   r=   rA   rP   rW   r^   rj   r   r   rS   r   r   <module>r      s*    
			     



#3 #3 #3 #3N
< 
< 
<
! 
! 
!
( 
( 
(      2( ( (E E E ER   0  &  *e e e eN>* >* >* >* >* >*r   