o
    iN{                     @  s`  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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mZmZmZ d dlmZ d dlmZ d dlmZmZmZmZmZ d dlZd dlZd dlm Z m!Z!m"Z" d d	l#m$Z$m%Z% erd d
l&m'Z' n	e$dddd\Z'Z(g dZ)dddZ*da+ej,j-j.Z/ej,j-j0Z1e2ej3j4Z5e5d Z6ej78ddej7d< e9dddZ:dd Z;edZ<edej=ej>Z?edd#d$Z@edd&d$Z@ddd'd$Z@dd*d+ZAdd,d-ZBddd2d3ZCddd8d9ZDdd<d=ZEddBdCZFdDdE fddJdKZGddLdMZHddNdOZIdddXdYZJdd[d\ZKe5ddfddbdcZLddde ZM	.dddkdlZNdddpdqZOdddtduZPG dvdw dwZQG dxdy dyZRdd|d}ZSd~d ZTddddZUddddZV	f	f	ddddZWdddZXddddZYdddZZddddZ[dddZ\G dd de'Z]G dd dZ^dd Z_dddZ`dddZadddZbdddZcdddZddS )    )annotationsN)literal_eval)CallableIterableSequence)log10)Path)TYPE_CHECKINGAnyTypeVarcastoverload)NdarrayOrTensorNdarrayTensorPathLike)optional_importversion_leq)
SafeLoaderyamlr   base)nameas_type)#zip_withstar_zip_withfirstissequenceiterableis_immutableensure_tupleensure_tuple_sizeensure_tuple_repto_tuple_of_dictionariesfall_back_tupleis_scalar_tensor	is_scalarprogress_barget_seedset_determinismlist_to_dictMAX_SEEDcopy_to_devicestr2boolstr2listMONAIEnvVarsImageMetaKeyis_module_ver_at_least
has_optionsample_slicescheck_parent_dirsave_objlabel_unionpath_to_uripprint_edgescheck_key_duplicatesCheckKeyDuplicatesYamlLoaderConvertUnits check_kwargs_exist_in_class_initrun_cmdvalstrreturnboolc                 C  s.   |   } | dv r
dS | dv rdS td|  )z
    Replaces deprecated (pre python 3.12)
    distutils strtobool function.

    True values are y, yes, t, true, on and 1;
    False values are n, no, f, false, off and 0.
    Raises ValueError if val is anything else.
    )yyesttrueon1T)nnoffalseoff0Fzinvalid truth value )lower
ValueErrorr;    rN   R/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/utils/misc.py
_strtoboolQ   s   	rP      ZCUBLAS_WORKSPACE_CONFIGz:4096:8)mapfuncc                G  s   || t | S )z`
    Map `op`, using `mapfunc`, to each tuple derived from zipping the iterables in `vals`.
    )zip)oprR   valsrN   rN   rO   r   n   s   r   c                 G  s   t | g|R dtjiS )z9
    Use starmap as the mapping function in zipWith.
    rR   )r   	itertoolsstarmap)rT   rU   rN   rN   rO   r   u   s   r   TNTiterableIterable[T]defaultc                 C     d S NrN   )rZ   r\   rN   rN   rO   r         r   T | Nonec                 C  r]   r^   rN   )rZ   rN   rN   rO   r      r_   c                 C  s   | D ]}|  S |S )zw
    Returns the first item in the given iterable or `default` if empty, meaningful mostly with 'for' expressions.
    rN   )rZ   r\   irN   rN   rO   r      s   objr
   c                 C  sN   zt | dr| jdkrW dS W n
 ty   Y dS w t| to&t| ttf S )zN
    Determine if the object is an iterable sequence and is not a string.
    ndimr   F)hasattrrc   	Exception
isinstancer   r<   bytesrb   rN   rN   rO   r      s   r   c                 C  s$   t | tdttttttttt	t
fS )z
    Determine if the object is an immutable object.

    see also https://github.com/python/cpython/blob/3.11/Lib/copy.py#L109
    N)rf   typeintfloatr>   complexr<   tuplerg   rangeslicerh   rN   rN   rO   r      s   $r   FrU   
wrap_arrayrm   c                 C  s2   |rt | tjtjfr| fS t| rt| S | fS )a#  
    Returns a tuple of `vals`.

    Args:
        vals: input data to convert to a tuple.
        wrap_array: if `True`, treat the input numerical array (ndarray/tensor) as one item of the tuple.
            if `False`, try to convert the array with `tuple(vals)`, default to `False`.

    )rf   npndarraytorchTensorr   rm   )rU   rp   rN   rN   rO   r      s   
r   dimrj   pad_valpad_from_startc                 C  sH   t | }|t| }|dkr|d| S |r|f| | S ||f|  S )zn
    Returns a copy of `tup` with `dim` values by either shortened or padded with `pad_val` as necessary.
    r   N)r   len)rU   ru   rv   rw   tupZpad_dimrN   rN   rO   r      s   r   ry   tuple[Any, ...]c                 C  sp   t | tjr|    } t | tjr|  } t	| s!| f| S t
| |kr+t| S td| dt
|  d)al  
    Returns a copy of `tup` with `dim` values by either shortened or duplicated input.

    Raises:
        ValueError: When ``tup`` is a sequence and ``tup`` length is not ``dim``.

    Examples::

        >>> ensure_tuple_rep(1, 3)
        (1, 1, 1)
        >>> ensure_tuple_rep(None, 3)
        (None, None, None)
        >>> ensure_tuple_rep('test', 3)
        ('test', 'test', 'test')
        >>> ensure_tuple_rep([1, 2, 3], 3)
        (1, 2, 3)
        >>> ensure_tuple_rep(range(3), 3)
        (0, 1, 2)
        >>> ensure_tuple_rep([1, 2], 3)
        ValueError: Sequence must have length 3, got length 2.

    zSequence must have length z, got .)rf   rs   rt   detachcpunumpyrq   rr   tolistr   rx   rm   rL   )ry   ru   rN   rN   rO   r      s   
r   dictionary_of_tuplesdictkeystuple[dict[Any, Any], ...]c                   sP   t tdkrti S fdd|  D  t fddttD S )a  
    Given a dictionary whose values contain scalars or tuples (with the same length as ``keys``),
    Create a dictionary for each key containing the scalar values mapping to that key.

    Args:
        dictionary_of_tuples: a dictionary whose values are scalars or tuples whose length is
            the length of ``keys``
        keys: a tuple of string values representing the keys in question

    Returns:
        a tuple of dictionaries that contain scalar values, one dictionary for each key

    Raises:
        ValueError: when values in the dictionary are tuples but not the same length as the length
        of ``keys``

    Examples:
        >>> to_tuple_of_dictionaries({'a': 1 'b': (2, 3), 'c': (4, 4)}, ("x", "y"))
        ({'a':1, 'b':2, 'c':4}, {'a':1, 'b':3, 'c':4})

    r   c                   s    i | ]\}}|t |t qS rN   )r   rx   .0kv)r   rN   rO   
<dictcomp>   s     z,to_tuple_of_dictionaries.<locals>.<dictcomp>c                 3  s&    | ]  fd d  D V  qdS )c                   s   i | ]	\}}||  qS rN   rN   r   ikrN   rO   r         z6to_tuple_of_dictionaries.<locals>.<genexpr>.<dictcomp>N)items)r   )dict_overridesr   rO   	<genexpr>  s   $ z+to_tuple_of_dictionaries.<locals>.<genexpr>)r   rx   rm   r   rn   )r   r   rN   )r   r   rO   r       s
   r    c                 C  s   | o| dkS Nr   rN   xrN   rN   rO   <lambda>  s    r   user_providedSequence | NdarrayTensorfuncr   c                   s.   t |}t| |}t fddt||D S )a$  
    Refine `user_provided` according to the `default`, and returns as a validated tuple.

    The validation is done for each element in `user_provided` using `func`.
    If `func(user_provided[idx])` returns False, the corresponding `default[idx]` will be used
    as the fallback.

    Typically used when `user_provided` is a tuple of window size provided by the user,
    `default` is defined by data, this function returns an updated `user_provided` with its non-positive
    components replaced by the corresponding components from `default`.

    Args:
        user_provided: item to be validated.
        default: a sequence used to provided the fallbacks.
        func: a Callable to validate every components of `user_provided`.

    Examples::

        >>> fall_back_tuple((1, 2), (32, 32))
        (1, 2)
        >>> fall_back_tuple(None, (32, 32))
        (32, 32)
        >>> fall_back_tuple((-1, 10), (32, 32))
        (32, 10)
        >>> fall_back_tuple((-1, None), (32, 32))
        (32, 32)
        >>> fall_back_tuple((1, None), (32, 32))
        (1, 32)
        >>> fall_back_tuple(0, (32, 32))
        (32, 32)
        >>> fall_back_tuple(range(3), (32, 64, 48))
        (32, 1, 2)
        >>> fall_back_tuple([0], (32, 32))
        ValueError: Sequence must have length 2, got length 1.

    c                 3  s$    | ]\}} |r|n|V  qd S r^   rN   )r   Z	default_cZuser_cr   rN   rO   r   -  s    
z"fall_back_tuple.<locals>.<genexpr>)rx   r   rm   rS   )r   r\   r   rc   userrN   r   rO   r!     s
   '
r!   c                 C  s   t | tjo
| jdkS r   )rf   rs   rt   rc   rM   rN   rN   rO   r"   2  s   r"   c                 C  s(   t | tjr| jdkrdS tt| S )Nr   T)rf   rs   rt   rc   r>   rq   isscalarrM   rN   rN   rO   r#   6  s   r#      indexcountdesc
str | Nonebar_lennewlineNonec                 C  s   |sdnd}t ||  | }|dur| dnd}|dd|  d||   d 7 }t|  d	| d| |d
 | |krAtd dS dS )a  print a progress bar to track some time consuming task.

    Args:
        index: current status in progress.
        count: total steps of the progress.
        desc: description of the progress bar, if not None, show before the progress bar.
        bar_len: the total length of the bar on screen, default is 30 char.
        newline: whether to print in a new line for every index.
    z
N  [=]/)end)rj   print)r   r   r   r   r   r   Z
filled_lenbarrN   rN   rO   r$   <  s   
 r$   
int | Nonec                   C  s   t S r^   )_seedrN   rN   rN   rO   r%   O  r_   r%   seeduse_deterministic_algorithmsbool | Noneadditional_settings<Sequence[Callable[[int], Any]] | Callable[[int], Any] | Nonec                 C  s   | du rt j t }t | nt| t } t |  | at|  tj|  |dur:t	|}|D ]}||  q3t j
 ! | durOdt j
j_dt j
j_n
tt j
j_tt j
j_W d   n1 scw   Y  |durst | dS dS )a>  
    Set random seed for modules to enable or disable deterministic training.

    Args:
        seed: the random seed to use, default is np.iinfo(np.int32).max.
            It is recommended to set a large seed, i.e. a number that has a good balance
            of 0 and 1 bits. Avoid having many 0 bits in the seed.
            if set to None, will disable deterministic training.
        use_deterministic_algorithms: Set whether PyTorch operations must use "deterministic" algorithms.
        additional_settings: additional settings that need to set random seed.

    Note:

        This function will not affect the randomizable objects in :py:class:`monai.transforms.Randomizable`, which
        have independent random states. For those objects, the ``set_random_state()`` method should be used to
        ensure the deterministic behavior (alternatively, :py:class:`monai.data.DataLoader` by default sets the seeds
        according to the global random state, please see also: :py:class:`monai.data.utils.worker_init_fn` and
        :py:class:`monai.data.utils.set_rnd`).
    NTF)rs   default_generatorr   r(   manual_seedrj   r   randomrq   r   backends__allow_nonbracketed_mutationcudnndeterministic	benchmark_flag_deterministic_flag_cudnn_benchmarkr   )r   r   r   Zseed_r   rN   rN   rO   r&   S  s.   





r&   c                 C  s   dd }i }| rJ| D ]?}||\}}z||v rt d| dt|||< W q
 tyI   zttt|||< W n tyF   |||< Y nw Y q
w |S )a9  
    To convert a list of "key=value" pairs into a dictionary.
    For examples: items: `["a=1", "b=2", "c=3"]`, return: {"a": "1", "b": "2", "c": "3"}.
    If no "=" in the pair, use None as the value, for example: ["a"], return: {"a": None}.
    Note that it will remove the blanks around keys and values.

    c                 S  sB   | j ddd}|d d}t|dkr|d dnd }||fS )Nr   rQ   )maxsplitr   z 
	')splitstriprx   )sr   keyvaluerN   rN   rO   
_parse_var  s   z list_to_dict.<locals>._parse_varzencounter duplicated key r{   )KeyErrorr   rL   r>   rP   r<   )r   r   ditemr   r   rN   rN   rO   r'     s$   	r'   Tdevicestr | torch.device | Nonenon_blockingverbosec                   s   t | dr| j dS t| trt fdd| D S t| tr, fdd| D S t| tr= fdd|  D S |rXttj	t
 jj}t| d	t|  d
  | S )a  
    Copy object or tuple/list/dictionary of objects to ``device``.

    Args:
        obj: object or tuple/list/dictionary of objects to move to ``device``.
        device: move ``obj`` to this device. Can be a string (e.g., ``cpu``, ``cuda``,
            ``cuda:0``, etc.) or of type ``torch.device``.
        non_blocking: when `True`, moves data to device asynchronously if
            possible, e.g., moving CPU Tensors with pinned memory to CUDA devices.
        verbose: when `True`, will print a warning for any elements of incompatible type
            not copied to ``device``.
    Returns:
        Same as input, copied to ``device`` where possible. Original input will be
            unchanged.
    to)r   c                 3  s    | ]	}t | V  qd S r^   r)   r   or   r   rN   rO   r     s    z!copy_to_device.<locals>.<genexpr>c                   s   g | ]}t | qS rN   r   r   r   rN   rO   
<listcomp>      z"copy_to_device.<locals>.<listcomp>c                   s   i | ]\}}|t | qS rN   r   )r   r   r   r   rN   rO   r     s    z"copy_to_device.<locals>.<dictcomp>z  called with incompatible type: z". Data will be returned unchanged.)rd   r   rf   rm   listr   r   r   types	FrameTypeinspectcurrentframef_codeco_namewarningswarnri   )rb   r   r   r   fn_namerN   r   rO   r)     s   



r)   r   
str | bool	raise_excc                 C  sf   t | tr| S d}d}t | tr |  } | |v rdS | |v r dS |r1td|  dd||  |S )a  
    Convert a string to a boolean. Case insensitive.
    True: yes, true, t, y, 1. False: no, false, f, n, 0.

    Args:
        value: string to be converted to a boolean. If value is a bool already, simply return it.
        raise_exc: if value not in tuples of expected true or false inputs,
            should we raise an exception? If not, return `default`.
    Raises
        ValueError: value not in tuples of expected true or false inputs and
            `raise_exc` is `True`.
    Useful with argparse, for example:
        parser.add_argument("--convert", default=False, type=str2bool)
        python mycode.py --convert=True
    )r@   rB   rA   r?   rD   )rF   rH   rG   rE   rJ   TFzGot "z", expected a value from: , )rf   r>   r<   rK   rL   join)r   r\   r   Ztrue_setZ	false_setrN   rN   rO   r*     s   

r*   str | list | Nonelist | Nonec              	   C  s   | du rdS t | tr| S t | tr9| d}tt|D ]}zt||  }|||< W q ty6   Y qw |S |rCt	d|  ddS )a  
    Convert a string to a list.  Useful with argparse commandline arguments:
        parser.add_argument("--blocks", default=[1,2,3], type=str2list)
        python mycode.py --blocks=1,2,2,4

    Args:
        value: string (comma separated) to be converted to a list
        raise_exc: if not possible to convert to a list, raise an exception
    Raises
        ValueError: value not a string or list or not possible to convert
    N,zUnable to convert "z-", expected a comma-separated str, e.g. 1,2,3)
rf   r   r<   r   rn   rx   r   r   re   rL   )r   r   r   ra   arN   rN   rO   r+     s"   


r+   c                   @  s   e Zd ZdZedddZedddZedd	d
ZedddZedddZ	edddZ
edddZedddZedddZdS )r,   z.
    Environment variables used by MONAI.
    r=   r   c                   C     t jdS )NZMONAI_DATA_DIRECTORYosenvirongetrN   rN   rN   rO   data_dir     zMONAIEnvVars.data_dirr>   c                  C  s$   t jdd} t| tr| S t| S )NZMONAI_DEBUGF)r   r   r   rf   r>   r*   rM   rN   rN   rO   debug  s   zMONAIEnvVars.debugc                   C  r   )NZMONAI_DOC_IMAGESr   rN   rN   rN   rO   
doc_images  r   zMONAIEnvVars.doc_imagesc                   C     t jddS )NZMONAI_ALGO_HASHZ21ed8e5r   rN   rN   rN   rO   	algo_hash      zMONAIEnvVars.algo_hashc                   C  r   )NZMONAI_TRACE_TRANSFORMrD   r   rN   rN   rN   rO   trace_transform$  r   zMONAIEnvVars.trace_transformc                   C  r   )NZMONAI_EVAL_EXPRrD   r   rN   rN   rN   rO   	eval_expr(  r   zMONAIEnvVars.eval_exprc                   C  r   )NZMONAI_ALLOW_MISSING_REFERENCErD   r   rN   rN   rN   rO   allow_missing_reference,  r   z$MONAIEnvVars.allow_missing_referencec                   C  r   )NZMONAI_EXTRA_TEST_DATArD   r   rN   rN   rN   rO   extra_test_data0  r   zMONAIEnvVars.extra_test_datac                   C  s   t jdd S )NZMONAI_TESTING_ALGO_TEMPLATEr   rN   rN   rN   rO   testing_algo_template4  r   z"MONAIEnvVars.testing_algo_templateN)r=   r   )r=   r>   )__name__
__module____qualname____doc__staticmethodr   r   r   r   r   r   r   r   r   rN   rN   rN   rO   r,     s(    r,   c                   @  s   e Zd ZdZdZdZdZdS )r-   z;
    Common key names in the metadata header of images
    filename_or_objZpatch_indexspatial_shapeN)r   r   r   r   ZFILENAME_OR_OBJZPATCH_INDEXSPATIAL_SHAPErN   rN   rN   rO   r-   9  s
    r-   keywordsstr | Sequence[str]c                   s0   t | sdS t|  t fddt|D S )zk
    Return a boolean indicating whether the given callable `obj` has the `keywords` in its signature.
    Fc                 3  s    | ]}| j v V  qd S r^   )
parameters)r   r   sigrN   rO   r   J  s    zhas_option.<locals>.<genexpr>)callabler   	signatureallr   )rb   r   rN   r   rO   r/   C  s   
r/   c                 C  s&   d tt|}| j|kot|| jS )a!  Determine if a module's version is at least equal to the given value.

    Args:
        module: imported module's name, e.g., `np` or `torch`.
        version: required version, given as a tuple, e.g., `(1, 8, 0)`.
    Returns:
        `True` if module is the given version or newer.
    r{   )r   mapr<   __version__r   )moduleversionZtest_verrN   rN   rO   r.   M  s   	r.   datar   
as_indices	slicevalsc                 G  s4   t dgt| j }|r|nt | ||< | t| S )a  sample several slices of input numpy array or Tensor on specified `dim`.

    Args:
        data: input data to sample slices, can be numpy array or PyTorch Tensor.
        dim: expected dimension index to sample slices, default to `1`.
        as_indices: if `True`, `slicevals` arg will be treated as the expected indices of slice, like: `1, 3, 5`
            means `data[..., [1, 3, 5], ...]`, if `False`, `slicevals` arg will be treated as args for `slice` func,
            like: `1, None` means `data[..., [1:], ...]`, `1, 5` means `data[..., [1: 5], ...]`.
        slicevals: indices of slices or start and end indices of expected slices, depends on `as_indices` flag.

    N)ro   rx   shaperm   )r  ru   r	  r
  slicesrN   rN   rO   r0   Z  s   r0   pathr   
create_dirc                 C  s>   t | } | j}| s|r|jdd dS td| ddS )a  
    Utility to check whether the parent directory of the `path` exists.

    Args:
        path: input path to check the parent directory.
        create_dir: if True, when the parent directory doesn't exist, create the directory,
            otherwise, raise exception.

    T)parentsz1the directory of specified path does not exist: `z`.N)r   parentexistsmkdirrL   )r  r  Zpath_dirrN   rN   rO   r1   l  s   
r1   objectatomicCallable | Nonekwargsc                 K  s   t |}t||d | rt| |du rtj}|s(|d| |d| dS z?t 0}t ||j	 }|d| |d| |
 rTtt|| W d   W dS W d   W dS 1 s`w   Y  W dS  tyq   Y dS w )a  
    Save an object to file with specified path.
    Support to serialize to a temporary file first, then move to final destination,
    so that files are guaranteed to not be damaged if exception occurs.

    Args:
        obj: input object data to save.
        path: target file path to save the input object.
        create_dir: whether to create dictionary of the path if not existing, default to `True`.
        atomic: if `True`, state is serialized to a temporary file first, then move to final destination.
            so that files are guaranteed to not be damaged if exception occurs. default to `True`.
        func: the function to save file, if None, default to `torch.save`.
        kwargs: other args for the save `func` except for the checkpoint and filename.
            default `func` is `torch.save()`, details of other args:
            https://pytorch.org/docs/stable/generated/torch.save.html.

    )r  r  N)rb   rG   rN   )r   r1   r  r   removers   savetempfileTemporaryDirectoryr   is_fileshutilmover<   PermissionError)rb   r  r  r  r   r  tempdir	temp_pathrN   rN   rO   r2     s*   

&r2   r   list | np.ndarrayr   c                 C  s   t ttt|  S )z
    Compute the union of class IDs in label and generate a list to include all class IDs
    Args:
        x: a list of numbers (for example, class_IDs)

    Returns
        a list showing the union (the union the class IDs)
    )r   setunionrq   arrayr   r   rN   rN   rO   r3     s   	r3         ?torch.Tensorsigmoid	thresholdrk   c                 K  s"   |st j| fi |S | |k S )z
    Compute the lab from the probability of predicted feature maps

    Args:
        sigmoid: If the sigmoid function should be used.
        threshold: threshold value to activate the sigmoid function.
    )rs   argmaxrj   )r   r'  r(  r  rN   rN   rO   
prob2class  s   "r*  c                 C  s   t |   S )z
    Convert a file path to URI. if not absolute path, will convert to absolute path first.

    Args:
        path: input file path to convert, can be a string or `Path` object.

    )r   absoluteas_uri)r  rN   rN   rO   r4     s   r4      n_linesc                 C  sp   t | d}t|d}t||d d kr3t||d  }|d| d| dg || d  }d|S )	z
    Pretty print the head and tail ``n_lines`` of ``val``, and omit the middle part if the part has more than 3 lines.

    Returns: the formatted string.
    TrQ         Nz
 ... omitted z
 line(s)

r   )pprintpformat
splitlinesmaxrx   r   )r;   r.  val_strZhidden_nrN   rN   rO   r5     s   
(
r5   ordered_pairsSequence[tuple[Any, Any]]dict[Any, Any]c                 C  sd   t  }| D ](\}}||v r(tjdddkrtd| dtd| d q|| qt| S )a  
    Checks if there is a duplicated key in the sequence of `ordered_pairs`.
    If there is - it will log a warning or raise ValueError
    (if configured by environmental var `MONAI_FAIL_ON_DUPLICATE_CONFIG==1`)

    Otherwise, it returns the dict made from this sequence.

    Satisfies a format for an `object_pairs_hook` in `json.load`

    Args:
        ordered_pairs: sequence of (key, value)
    MONAI_FAIL_ON_DUPLICATE_CONFIGrJ   rD   Duplicate key: ``)	r"  r   r   r   rL   r   r   addr   )r6  r   r   _rN   rN   rO   r6     s   r6   c                      s   e Zd Zd fdd	Z  ZS )r7   Fc                   sx   t  }|jD ].\}}| j||d}||v r/tjdddkr&td| dtd| d |	| qt
 ||S )N)deepr9  rJ   rD   r:  r;  )r"  r   Zconstruct_objectr   r   r   rL   r   r   r<  superconstruct_mapping)selfnoder>  mappingZkey_noder=  r   	__class__rN   rO   r@    s   z.CheckKeyDuplicatesYamlLoader.construct_mappingF)r   r   r   r@  __classcell__rN   rN   rD  rO   r7     s    r7   c                   @  st   e Zd ZdZdddddZddd	d
dddddddddddZg dZd*ddZdd Zd d! Z	d"d# Z
d+d'd(Zd)S ),r8   z
    Convert the values from input unit to the target unit

    Args:
        input_unit: the unit of the input quantity
        target_unit: the unit of the target quantity

    g
F%u?gׁ?gB?gL7A`%@)inchfootZyardZmile      	      r0  r/  rQ   iiii)ZpetaZteraZgigaZmegaZkiloZhectoZdecaZdeciZcentimillimicronanoZpicoZfemto)meterbytebit
input_unitr<   target_unitr=   r   c                 C  sR   |  |\| _}|  |\| _}||kr|| _n
td| d| |  | _d S )NzPBoth input and target units should be from the same quantity. Input quantity is z while target quantity is )_get_valid_unit_and_baserW  rX  	unit_baserL   _calculate_conversion_factorconversion_factor)rA  rW  rX  Z
input_baseZtarget_baserN   rN   rO   __init__%  s   zConvertUnits.__init__c                 C  sP   t | }|| jv r|dfS | jD ]}||r||f  S qtd| d)NrT  z3Currently, it only supports length conversion but `z` is given.)r<   rK   imperial_unit_of_length
base_unitsendswithrL   )rA  unitZ	base_unitrN   rN   rO   rY  1  s   


z%ConvertUnits._get_valid_unit_and_basec                 C  s@   || j v rt| j | S |dt| j }|dkrdS | j| S )zDCalculate the power of the unit factor with respect to the base unitNr         ?)r^  r   rx   rZ  unit_prefix)rA  ra  prefixrN   rN   rO   _get_unit_power:  s   

zConvertUnits._get_unit_powerc                 C  s4   | j | jkrdS | | j }| | j}d||  S )z?Calculate unit conversion factor with respect to the input unitrb  
   )rW  rX  re  )rA  Zinput_powerZtarget_powerrN   rN   rO   r[  D  s
   z)ConvertUnits._calculate_conversion_factorr   int | floatr
   c                 C  s   t || j S r^   )rk   r\  )rA  r   rN   rN   rO   __call__L  s   zConvertUnits.__call__N)rW  r<   rX  r<   r=   r   )r   rg  r=   r
   )r   r   r   r   r^  rc  r_  r]  rY  re  r[  rh  rN   rN   rN   rO   r8     s0    	
	
r8   c                 C  s:   t | j}t|jdh }t|}|| }|t k|fS )a   
    Check if the all keys in kwargs exist in the __init__ method of the class.

    Args:
        cls: the class to check.
        kwargs: kwargs to examine.

    Returns:
        a boolean indicating if all keys exist.
        a set of extra keys that are not used in the __init__.
    rA  )r   r  r]  r"  r   )clsr  Zinit_signatureZinit_paramsZinput_kwargsextra_kwargsrN   rN   rO   r9   P  s
   r9   cmd_list	list[str]subprocess.CompletedProcessc                 K  s   t  }|d||d< |ddr!ddl}|jjd|   z
t	j
| fi |W S  t	jy] } z%|s7 t|jjdd}t|jjdd}td	|j d
| d| d|d}~ww )a  
    Run a command by using ``subprocess.run`` with capture_output=True and stderr=subprocess.STDOUT
    so that the raise exception will have that information. The argument `capture_output` can be set explicitly
    if desired, but will be overriden with the debug status from the variable.

    Args:
        cmd_list: a list of strings describing the command to run.
        kwargs: keyword arguments supported by the ``subprocess.run`` method.

    Returns:
        a CompletedProcess instance after the command completes.
    capture_outputZrun_cmd_verboseFr   Nzmonai.utils.run_cmdreplace)errorszsubprocess call error z: r   r{   )r,   r   r   popmonaiappsutils
get_loggerinfo
subprocessrunCalledProcessErrorr<   stdoutdecodestderrRuntimeError
returncode)rk  r  r   rr  eoutputrp  rN   rN   rO   r:   d  s    r:   numSequence[int] | intc                 C  s6   t | } dd | D }dd t||D }t || kS )zS
    Determine if the input is a square number or a squence of square numbers.
    c                 S  s   g | ]	}t t|qS rN   )rj   mathsqrt)r   Z_numrN   rN   rO   r     r   zis_sqrt.<locals>.<listcomp>c                 S  s   g | ]\}}|| qS rN   rN   )r   _iZ_jrN   rN   rO   r     r   )r   rS   )r  Zsqrt_numretrN   rN   rO   is_sqrt  s   r  arrrc   c                 C  s   | dd|| j     S )zMAppend 1-sized dimensions to `arr` to create a result with `ndim` dimensions.).r^   rc   r  rc   rN   rN   rO   unsqueeze_right  s   r  c                 C  s   | d|| j    S )zNPrepend 1-sized dimensions to `arr` to create a result with `ndim` dimensions.r^   r  r  rN   rN   rO   unsqueeze_left  s   r  metricsdict[str, Any]c                 C  s<   i }|   D ]\}}t|tr|t| q|||< q|S )z=
    Flatten the nested dictionary to a flat dictionary.
    )r   rf   r   updateflatten_dict)r  resultr   r   rN   rN   rO   r    s   

r  )r;   r<   r=   r>   )rZ   r[   r\   rX   r=   rX   )rZ   r[   r=   r`   r^   )rZ   r[   r\   r`   r=   r`   )rb   r
   r=   r>   rF  )rU   r
   rp   r>   r=   rm   )r   F)
rU   r
   ru   rj   rv   r
   rw   r>   r=   rm   )ry   r
   ru   rj   r=   rz   )r   r   r   r
   r=   r   )r   r
   r\   r   r   r   r=   rz   )r;   r
   r=   r>   )Nr   F)r   rj   r   rj   r   r   r   rj   r   r>   r=   r   )r=   r   )r   r   r   r   r   r   r=   r   )TF)
rb   r
   r   r   r   r>   r   r>   r=   r
   )FT)r   r   r\   r>   r   r>   r=   r>   )T)r   r   r   r>   r=   r   )rb   r   r   r   r=   r>   )rQ   T)
r  r   ru   rj   r	  r>   r
  rj   r=   r   )r  r   r  r>   r=   r   )TTN)rb   r  r  r   r  r>   r  r>   r   r  r  r
   r=   r   )r   r!  r=   r   )Fr%  )
r   r&  r'  r>   r(  rk   r  r
   r=   r&  )r  r   r=   r<   )r-  )r;   r
   r.  rj   r=   r<   )r6  r7  r=   r8  )rk  rl  r  r
   r=   rm  )r  r  r=   r>   )r  rY   rc   rj   r=   rY   )r  r  r=   r  )e
__future__r   r   rV   r  r   r1  r   r  rw  r  r   r   astr   collections.abcr   r   r   r   pathlibr   typingr	   r
   r   r   r   r~   rq   rs   Zmonai.config.type_definitionsr   r   r   monai.utils.moduler   r   r   r   r=  __all__rP   r   r   r   r   r   r   r   iinfouint32r4  ZNP_MAXr(   r   r   r  r   r   rX   rr   rt   rY   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r)   r*   r+   r,   r-   r/   r.   r0   r1   r2   r3   r*  r4   r5   r6   r7   r8   r9   r:   r  r  r  r  rN   rN   rN   rO   <module>   s   
'


	
	

# 
.

6!"# +



0

I




