U
    Phx                  #   @  sv  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 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*ddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2g#Z+da,e j-j.j/Z0e j-j.j1Z2e3ej4j5Z6e6d3 Z7e8d4d5dZ9d6d Z:ed7Z;ed8d7d7d9d:dZ<ed8d;d<d=dZ<dd8d;d;d9d>dZ<d?d@dAdBdZ=d?d@dAdCdZ>dd?d@dEdFdGdZ?dd?dHd?d@dEdIdJdZ@d?dHdKdLdMdZAdNd?dOdPdQdZBdRdS fd?dTdUdKdVdWdZCd?d@dXdYdZDd?d@dXdZdZEddHdHd\dHd@d]d^d_dZFd`dadbdZGe6ddfd`dcddd]dedfdZHdgd ZIdd?did@d@d?djdkd!ZJddld@d@d@dmdnd"ZKddod@dpdqdrd#ZLG dsd$ d$ZMG dtd% d%ZNdUdud@dvdwd'ZOdxd& ZPddydHd@dHdydzd{d(ZQdd|d@d]d}d~d)ZRddd|d@d@dd?d]ddd*ZSddddd+ZTddd@dd?ddddZUd|dddd,ZVdd?dHdddd-ZWddddd.ZXG dd/ d/e)ZYG dd0 d0ZZdd1 Z[dd?dddd2Z\dd@dddZ]dydHdydddZ^dydHdydddZ_dS )    )annotationsN)literal_eval)CallableIterableSequence)	strtobool)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   )mapfuncc                G  s   || t | S )z`
    Map `op`, using `mapfunc`, to each tuple derived from zipping the iterables in `vals`.
    )zip)opr=   vals rA   E/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/utils/misc.pyr   X   s    c                 G  s   t | f|dtjiS )z9
    Use starmap as the mapping function in zipWith.
    r=   )r   	itertoolsstarmap)r?   r@   rA   rA   rB   r   _   s    TzIterable[T])iterabledefaultreturnc                 C  s   d S NrA   )rF   rG   rA   rA   rB   r   i   s    zT | None)rF   rH   c                 C  s   d S rI   rA   )rF   rA   rA   rB   r   m   s    c                 C  s   | D ]
}|  S |S )zw
    Returns the first item in the given iterable or `default` if empty, meaningful mostly with 'for' expressions.
    rA   )rF   rG   irA   rA   rB   r   q   s    r   bool)objrH   c                 C  sP   zt | dr| jdkrW dS W n tk
r4   Y dS X t| toNt| ttf S )zN
    Determine if the object is an iterable sequence and is not a string.
    ndimr   F)hasattrrM   	Exception
isinstancer   strbytesrL   rA   rA   rB   r   z   s    
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)rP   typeintfloatrK   complexrQ   tuplerR   rangeslicerS   rA   rA   rB   r      s    FrX   )r@   
wrap_arrayrH   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`.

    )rP   npndarraytorchTensorr   rX   )r@   r[   rA   rA   rB   r      s    
rU   )r@   dimpad_valpad_from_startrH   c                 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)r@   r`   ra   rb   tupZpad_dimrA   rA   rB   r      s    ztuple[Any, ...])rd   r`   rH   c                 C  st   t | tjr|    } t | tjr0|  } t	| sB| f| S t
| |krVt| S td| dt
|  ddS )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 .N)rP   r^   r_   detachcpunumpyr\   r]   tolistr   rc   rX   
ValueError)rd   r`   rA   rA   rB   r       s    
dictztuple[dict[Any, Any], ...])dictionary_of_tupleskeysrH   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 rA   )r    rc   .0kv)rm   rA   rB   
<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 rA   rA   rn   ikrA   rB   rr      s      z6to_tuple_of_dictionaries.<locals>.<genexpr>.<dictcomp>N)items)ro   )dict_overridesrs   rB   	<genexpr>   s     z+to_tuple_of_dictionaries.<locals>.<genexpr>)r   rc   rX   ru   rY   )rl   rm   rA   )rv   rm   rB   r!      s
    c                 C  s   | o
| dkS Nr   rA   xrA   rA   rB   <lambda>       r{   zSequence | NdarrayTensorr   )user_providedrG   funcrH   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 rI   rA   )ro   Z	default_cZuser_cr~   rA   rB   rw     s    z"fall_back_tuple.<locals>.<genexpr>)rc   r    rX   r>   )r}   rG   r~   rM   userrA   r   rB   r"      s
    '
)valrH   c                 C  s   t | tjo| jdkS rx   )rP   r^   r_   rM   r   rA   rA   rB   r#     s    c                 C  s(   t | tjr| jdkrdS tt| S )Nr   T)rP   r^   r_   rM   rK   r\   isscalarr   rA   rA   rB   r$     s       
str | NoneNone)indexcountdescbar_lennewlinerH   c                 C  s   |sdnd}t ||  | }|dk	r.| dnd}|dd|  d||   d 7 }t|  d	| d| |d
 | |kr~td 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)rU   print)r   r   r   r   r   r   Z
filled_lenbarrA   rA   rB   r%   %  s    
 z
int | NonerH   c                   C  s   t S rI   )_seedrA   rA   rA   rB   r&   8  s    zbool | Nonez<Sequence[Callable[[int], Any]] | Callable[[int], Any] | None)seeduse_deterministic_algorithmsadditional_settingsrH   c                 C  s  | dkr"t j t }t | nt| t } t |  | at|  tj|  |dk	rtt	|}|D ]}||  qft j
 rtd dt j
_| dk	rdt j
j_dt j
j_ntt j
j_tt j
j_|dk	rtt drt | n tt drt | n
td 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`).
    Nz[PyTorch global flag support of backends is disabled, enable it to set global `cudnn` flags.TFr   set_deterministiczRuse_deterministic_algorithms=True, but PyTorch version is too old to set the mode.)r^   default_generatorr   r)   manual_seedrU   r   randomr\   r   backendsflags_frozenwarningswarn"__allow_nonbracketed_mutation_flagcudnndeterministic	benchmark_flag_deterministic_flag_cudnn_benchmarkrN   r   r   )r   r   r   Zseed_r~   rA   rA   rB   r'   <  s4    










c                 C  s   dd }i }| r| D ]}||\}}z(||kr>t d| dt|||< W q tk
r   zttt|||< W n tk
r   |||< Y nX Y qX q|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r6|d dnd }||fS )Nr   r<   )maxsplitr   z 
	')splitstriprc   )sru   keyvaluerA   rA   rB   
_parse_var  s    z list_to_dict.<locals>._parse_varzencounter duplicated key re   )KeyErrorr   rj   rK   r   rQ   )ru   r   ditemr   r   rA   rA   rB   r(   y  s    	Tzstr | torch.device | None)rL   devicenon_blockingverboserH   c                   s   t | dr| j dS t| tr:t fdd| D S t| trX fdd| D S t| trz fdd|  D S |rt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 rI   r*   ro   or   r   rA   rB   rw     s     z!copy_to_device.<locals>.<genexpr>c                   s   g | ]}t | qS rA   r   r   r   rA   rB   
<listcomp>  s     z"copy_to_device.<locals>.<listcomp>c                   s   i | ]\}}|t | qS rA   r   )ro   rp   r   r   rA   rB   rr     s      z"copy_to_device.<locals>.<dictcomp>z  called with incompatible type: z". Data will be returned unchanged.)rN   r   rP   rX   listrk   ru   r   types	FrameTypeinspectcurrentframef_codeco_namer   r   rT   )rL   r   r   r   fn_namerA   r   rB   r*     s    



z
str | bool)r   rG   	raise_excrH   c                 C  sf   t | tr| S d}d}t | tr@|  } | |kr4dS | |kr@dS |rbt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
    )yestruety1)nofalsefn0TFzGot "z", expected a value from: , )rP   rK   rQ   lowerrj   join)r   rG   r   Ztrue_setZ	false_setrA   rA   rB   r+     s    

zstr | list | Nonezlist | None)r   r   rH   c              	   C  s   | dkrdS t | tr| S t | trv| d}tt|D ]6}zt||  }|||< W q: tk
rn   Y q:X q:|S |rt	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)
rP   r   rQ   r   rY   rc   r   r   rO   rj   )r   r   rq   rJ   arA   rA   rB   r,     s     


c                   @  s   e Zd ZdZeddddZeddddZeddd	d
ZeddddZeddddZ	eddddZ
eddddZeddddZeddddZdS )r-   z.
    Environment variables used by MONAI.
    r   r   c                   C  s   t jdS )NZMONAI_DATA_DIRECTORYosenvirongetrA   rA   rA   rB   data_dir  s    zMONAIEnvVars.data_dirrK   c                  C  s$   t jdd} t| tr| S t| S )NZMONAI_DEBUGF)r   r   r   rP   rK   r+   r   rA   rA   rB   debug  s    zMONAIEnvVars.debugc                   C  s   t jdS )NZMONAI_DOC_IMAGESr   rA   rA   rA   rB   
doc_images  s    zMONAIEnvVars.doc_imagesc                   C  s   t jddS )NZMONAI_ALGO_HASHZe4cf5a1r   rA   rA   rA   rB   	algo_hash  s    zMONAIEnvVars.algo_hashc                   C  s   t jddS )NZMONAI_TRACE_TRANSFORMr   r   rA   rA   rA   rB   trace_transform  s    zMONAIEnvVars.trace_transformc                   C  s   t jddS )NZMONAI_EVAL_EXPRr   r   rA   rA   rA   rB   	eval_expr  s    zMONAIEnvVars.eval_exprc                   C  s   t jddS )NZMONAI_ALLOW_MISSING_REFERENCEr   r   rA   rA   rA   rB   allow_missing_reference  s    z$MONAIEnvVars.allow_missing_referencec                   C  s   t jddS )NZMONAI_EXTRA_TEST_DATAr   r   rA   rA   rA   rB   extra_test_data   s    zMONAIEnvVars.extra_test_datac                   C  s   t jdd S )NZMONAI_TESTING_ALGO_TEMPLATEr   rA   rA   rA   rB   testing_algo_template$  s    z"MONAIEnvVars.testing_algo_templateN)__name__
__module____qualname____doc__staticmethodr   r   r   r   r   r   r   r   r   rA   rA   rA   rB   r-     s&   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_SHAPErA   rA   rA   rB   r.   )  s   zstr | Sequence[str])rL   keywordsrH   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 kV  qd S rI   )
parameters)ro   r   sigrA   rB   rw   :  s     zhas_option.<locals>.<genexpr>)callabler   	signatureallr   )rL   r   rA   r   rB   r0   3  s    
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.
    re   )r   maprQ   __version__r   )moduleversionZtest_verrA   rA   rB   r/   =  s    	r   )datar`   
as_indices	slicevalsrH   c                 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)rZ   rc   shaperX   )r   r`   r   r   slicesrA   rA   rB   r1   J  s    r   )path
create_dirrH   c                 C  s<   t | } | j}| s8|r(|jdd n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mkdirrj   )r   r   Zpath_dirrA   rA   rB   r2   \  s    
objectzCallable | None)rL   r   r   atomicr~   kwargsrH   c              	   K  s   t |}t||d | r&t| |dkr4tj}|sP|f | |d| dS zRt @}t ||j	 }|f | |d| |
 rtt|| W 5 Q R X W n tk
r   Y nX dS )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)rL   r   )r	   r2   r   r   remover^   savetempfileTemporaryDirectoryr   is_fileshutilmoverQ   PermissionError)rL   r   r   r   r~   r  tempdir	temp_pathrA   rA   rB   r3   o  s"    

zlist | np.ndarrayr   )rz   rH   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unionr\   arrayri   ry   rA   rA   rB   r4     s    	      ?ztorch.TensorrV   )rz   sigmoid	thresholdr  rH   c                 K  s   |st j| f|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.
    )r^   argmaxrU   )rz   r  r  r  rA   rA   rB   
prob2class  s    r  rQ   )r   rH   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   rA   rA   rB   r5     s       )r   n_linesrH   c                 C  sp   t | d}t|d}t||d d krft||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.
    Tr<         Nz
 ... omitted z
 line(s)

r   )pprintpformat
splitlinesmaxrc   r   )r   r  val_strZhidden_nrA   rA   rB   r6     s    
(zSequence[tuple[Any, Any]]zdict[Any, Any])ordered_pairsrH   c                 C  sf   t  }| D ]R\}}||krRtjdddkr>td| dq\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_CONFIGr   r   Duplicate key: ``)	r  r   r   r   rj   r   r   addrk   )r  rm   rp   _rA   rA   rB   r7     s    c                      s   e Zd Zd fdd	Z  ZS )r8   Fc                   sz   t  }|jD ]^\}}| j||d}||kr`tjdddkrNtd| dntd| d |	| qt
 ||S )N)deepr   r   r   r!  r"  )r  r   Zconstruct_objectr   r   r   rj   r   r   r#  superconstruct_mapping)selfnoder%  mappingZkey_noder$  r   	__class__rA   rB   r'    s    z.CheckKeyDuplicatesYamlLoader.construct_mapping)F)r   r   r   r'  __classcell__rA   rA   r+  rB   r8     s   c                   @  s   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dddgZddddddZdd Zd d! Z	d"d# Z
d$d%d&d'd(Zd)S )*r9   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      	      r  r  r<   iiii)ZpetaZteraZgigaZmegaZkiloZhectoZdecaZdeciZcentimillimicronanoZpicoZfemtometerbytebitrQ   r   )
input_unittarget_unitrH   c                 C  sP   |  |\| _}|  |\| _}||kr0|| _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_baser=  r>  	unit_baserj   _calculate_conversion_factor)r(  r=  r>  Z
input_baseZtarget_baserA   rA   rB   __init__  s    zConvertUnits.__init__c                 C  sT   t | }|| jkr|dfS | jD ]}||r$||f  S q$td| dd S )Nr:  z3Currently, it only supports length conversion but `z` is given.)rQ   r   imperial_unit_of_length
base_unitsendswithrj   )r(  unitZ	base_unitrA   rA   rB   r?  !  s    


z%ConvertUnits._get_valid_unit_and_basec                 C  s@   || j krt| j | S |dt| j }|dkr6dS | j| S )zDCalculate the power of the unit factor with respect to the base unitNr         ?)rC  r   rc   r@  unit_prefix)r(  rF  prefixrA   rA   rB   _get_unit_power*  s    
zConvertUnits._get_unit_powerc                 C  s:   | j | jkrdS | | j }| | j}d||  | _dS )z?Calculate unit conversion factor with respect to the input unitrG  
   N)r=  r>  rJ  conversion_factor)r(  Zinput_powerZtarget_powerrA   rA   rB   rA  4  s
    z)ConvertUnits._calculate_conversion_factorzint | floatr   )r   rH   c                 C  s   t || j S rI   )rV   rL  )r(  r   rA   rA   rB   __call__<  s    zConvertUnits.__call__N)r   r   r   r   rC  rH  rD  rB  r?  rJ  rA  rM  rA   rA   rA   rB   r9     s.   	
	
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__.
    r(  )r   r   rB  r  r   )clsr  Zinit_signatureZinit_paramsinput_kwargsextra_kwargsrA   rA   rB   r:   @  s
    z	list[str]zsubprocess.CompletedProcess)cmd_listr  rH   c                 K  s   t  }|d||d< |ddrBddl}|jjd|   zt	j
| f|W S  t	jk
r } zN|sl t|jjdd}t|jjdd}td	|j d
| d| d|W 5 d}~X Y nX dS )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   Nr;   replace)errorszsubprocess call error z: r   re   )r-   r   r   popmonaiappsutils
get_loggerinfo
subprocessrunCalledProcessErrorrQ   stdoutdecodestderrRuntimeError
returncode)rQ  r  r   rV  eoutputrT  rA   rA   rB   r;   T  s    zSequence[int] | int)numrH   c                 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 rA   )rU   mathsqrt)ro   _numrA   rA   rB   r   w  s     zis_sqrt.<locals>.<listcomp>c                 S  s   g | ]\}}|| qS rA   rA   )ro   _iZ_jrA   rA   rB   r   x  s     )r   r>   )re  Zsqrt_numretrA   rA   rB   is_sqrtr  s    rk  )arrrM   rH   c                 C  s   | dd|| j     S )zMAppend 1-sized dimensions to `arr` to create a result with `ndim` dimensions.).rI   rM   rl  rM   rA   rA   rB   unsqueeze_right|  s    ro  c                 C  s   | d|| j    S )zNPrepend 1-sized dimensions to `arr` to create a result with `ndim` dimensions.rI   rm  rn  rA   rA   rB   unsqueeze_left  s    rp  )N)F)r   F)Nr   F)TF)FT)T)r<   T)T)TTN)Fr  )r  )`
__future__r   r   rC   rf  r   r  r   r  r[  r  r   r   astr   collections.abcr   r   r   distutils.utilr   r   pathlibr	   typingr
   r   r   r   r   rh   r\   r^   Zmonai.config.type_definitionsr   r   r   monai.utils.moduler   r   r   r   r$  __all__r   r   r   r   r   r   r   iinfouint32r  ZNP_MAXr)   r   r   r   rE   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r*   r+   r,   r-   r.   r0   r/   r1   r2   r3   r4   r  r5   r6   r7   r8   r9   r:   r;   rk  ro  rp  rA   rA   rA   rB   <module>   s   &

		# .=!   "# +

   0I
