U Pha@sddlmZddlZddlZddlZddlZddlZddlZddlZddl m Z m Z m Z m Z ddlmZmZddlmZddlmZddlmZddlmZdd lmZmZdd lmZmZmZddlZej d d d kZ!ej dd d kZ"ej dd d kZ#dZ$dddddddddddddddd d!gZ%dSd$d%d&d'd&d(d)dZ&d*d*d+d,d-dZ'd.dZ(dTd0d'd*d1d2d3dZ)d*d*d&d&d4d5dZ*d6dZ+dUd&d*d&d'd8d9dZ,dVd&d*d&d'd:d;dZ-Gdd?fd*d*d@d*d*d&d'd*dAdB dCdZ2d7e,d#fd*d*d@d'dDdEdFdZ3dWdHdZ4e5ddIdZ6d*d*dJdKdLdMZ7d*d*d'dKdNdZ8d*d*d'dKdOd Z9e5ddXd+d+d+dPd'dQdRd!Z:dS)Y) annotationsN)Callable CollectionHashableMapping)partialwraps) import_module) walk_packages)locate)match) FunctionType ModuleType)AnyIterablecastZMONAI_EVAL_EXPR10ZMONAI_DEBUG_CONFIGZMONAI_ALLOW_MISSING_REFERENCEz{}InvalidPyTorchVersionErrorOptionalImportError exact_versionexportdamerau_levenshtein_distancelook_up_option min_versionoptional_import require_pkgload_submodules instantiateget_full_type_nameget_package_versionget_torch_version_tuple version_leq version_geq pytorch_after no_defaultTrzCollection | enum.EnumMetarbool)opt_str supporteddefaultprint_all_optionsreturnc Cst|ts$tdt|d|dt|tr6|}t|tjrt|trf|dd|Dkrf||St|tjr||kr|Sn0t|t r||kr||St|t r||kr|S|dkr|St|tjrdd|D}n|dk rt |nt }|std |di}|}|D]$}t ||}|d kr|||<q|rJd |d nd }|rt ||jd} td|d| dd|d|td|d|dS)a3 Look up the option in the supported collection and return the matched item. Raise a value error possibly with a guess of the closest match. Args: opt_str: The option string or Enum to look up. supported: The collection of supported options, it can be list, tuple, set, dict, or Enum. default: If it is given, this method will return `default` when `opt_str` is not found, instead of raising a `ValueError`. Otherwise, it defaults to `"no_default"`, so that the method may raise a `ValueError`. print_all_options: whether to print all available options when `opt_str` is not found. Defaults to True Examples: .. code-block:: python from enum import Enum from monai.utils import look_up_option class Color(Enum): RED = "red" BLUE = "blue" look_up_option("red", Color) # look_up_option(Color.RED, Color) # look_up_option("read", Color) # ValueError: By 'read', did you mean 'red'? # 'read' is not a valid option. # Available options are {'blue', 'red'}. look_up_option("red", {"red", "blue"}) # "red" Adapted from https://github.com/NifTK/NiftyNet/blob/v0.6.0/niftynet/utilities/util_common.py#L249 zUnrecognized option type: :.cSsh|] }|jqSvalue.0itemr.r.G/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/utils/module.py isz!look_up_option..r%cSsh|] }|jqSr.r/r1r.r.r4r5{sNzNo options available: zAvailable options are z. )keyzBy 'z', did you mean 'z'? 'z' is not a valid value. zUnsupported option 'z', ) isinstancer ValueErrortypestrstripenumEnumMetaEnumrrsetrminget) r'r(r)r*Z set_to_checkZ edit_distsr8Z edit_distZ supported_msgZguess_at_spellingr.r.r4r?sJ%        r=int)s1s2r+c CsN||kr dSt|}t|}|s$|S|s,|Sddtd|dD}td|dD]}|d|d|f<qRt|D]\}}t|D]\}}||krdnd} t||d|fd|||dfd||d|df| |||f<|r|r|||dkr||d|krt|||f||d|df| |||f<qqp||d|dfS)u Calculates the Damerau–Levenshtein distance between two strings for spelling correction. https://en.wikipedia.org/wiki/Damerau–Levenshtein_distance rcSsi|]}|df|dqS)r.)r2ir.r.r4 sz0damerau_levenshtein_distance..rHrI)lenrange enumeraterC) rFrGZstring_1_lengthZstring_2_lengthdjrJs1iZs2jcostr.r.r4rs, (2csfdd}|S)aA Make the decorated object a member of the named module. This will also add the object under its aliases if it has a `__aliases__` member, thus this decorator should be before the `alias` decorator to pick up those names. Alias names which conflict with package names or existing members will be ignored. csNt}t||jsJt||j|t|ddD]}t||s.t|||q.|S)N __aliases__r.)r hasattr__name__setattrgetattr)objmodaliasmodnamer.r4_inners  zexport.._innerr.)r]r^r.r\r4rs (.*[tT]est.*)|(_.*)rz"tuple[list[ModuleType], list[str]])basemodload_allexclude_patternr+c Csg}g}t|j|jd|jdD]\}}}|s2|r |tjkr t||dkr z(t|}||j |||Wq t k rYq t k r} z(d} t | | d| | j| W5d} ~ XYq Xq ||fS)z Traverse the source of the module structure starting with module `basemod`, loading all packages plus all files if `load_all` is True, excluding anything whose name matches `exclude_pattern`. r-)prefixonerrorNz Multiple versions of MONAI may have been installed? Please see the installation guide: https://docs.monai.io/en/stable/installation.html  )r __path__rVappendsysmodulesr r find_specloader load_moduler ImportErrorr<with_traceback __traceback__) r`rarb submodulesZerr_modimporternameZis_pkgrZemsgr.r.r4rs& 4)__path__modekwargsr+c Kslddlm}t|trt|n|}|dkr:td|dt||}z|ddsVtrtt d|d |d t t |st d |d |d |WS||j kr|f|WS||jkr|rt|f|n|WS||jkrt d|d |d tj|f|WSWnNtk rT}z.td|dd|d|jd|W5d}~XYnXt d|d |S)a Create an object instance or call a callable object from a class or function represented by ``_path``. `kwargs` will be part of the input arguments to the class constructor or function. The target component must be a class or a function, if not, return the component directly. Args: __path: if a string is provided, it's interpreted as the full path of the target class or function component. If a callable is provided, ``__path(**kwargs)`` will be invoked and returned for ``__mode="default"``. For ``__mode="callable"``, the callable will be returned as ``__path`` or, if ``kwargs`` are provided, as ``functools.partial(__path, **kwargs)`` for future invoking. __mode: the operating mode for invoking the (callable) ``component`` represented by ``__path``: - ``"default"``: returns ``component(**kwargs)`` - ``"callable"``: returns ``component`` or, if ``kwargs`` are provided, ``functools.partial(component, **kwargs)`` - ``"debug"``: returns ``pdb.runcall(component, **kwargs)`` kwargs: keyword arguments to the callable represented by ``__path``. r) CompInitModeNz'Cannot locate class or function path: 'z'.Z_debug_Fz pdb: instantiating component=z, mode=zV See also Debugger commands documentation: https://docs.python.org/3/library/pdb.html z Component z is not callable when mode=r-z!Failed to instantiate component 'z' with keywords: ,z set '_mode_=z' to enter the debugging mode.zKComponent to instantiate must represent a valid class or function, but got )monai.utils.enumsrxr:r=r ModuleNotFoundErrorrpop run_debugwarningswarn breakpointcallableDEFAULTZCALLABLErDEBUGpdbZruncall Exception RuntimeErrorjoinkeys)rurvrwrx componentmrsr.r.r4rs>      "cCs.|j}|dks|tjjkr |jS|d|jS)zG Utility to get the full path name of a class or object type. Nr-) __module__r= __class__rV)typeobjmoduler.r.r4rsr7) the_modulemin_version_str_argsr+cGs\|rt|dsdStdd|jdddD}tdd|dddD}||kS) z Convert version strings into tuples of int and compare them. Returns True if the module's version is greater or equal to the 'min_version'. When min_version_str is not provided, it always returns True. __version__Tcss|]}t|VqdSNrEr2xr.r.r4 0szmin_version..r-NrLcss|]}t|VqdSrrrr.r.r4r1s)rUtuplersplit)rrrZ mod_versionrequiredr.r.r4r&s " )r version_strrr+cGs,t|dst|ddSt|j|kS)zF Returns True if the module's __version__ matches version_str rz5 has no attribute __version__ in exact_version check.F)rUr~rr&r)rrrr.r.r4r5s cs eZdZdZfddZZS)rzo Raised when called function or method requires a more recent PyTorch version than that installed. cs |d|d}t|dS)Nz requires PyTorch version z or later)super__init__)selfZrequired_versionrrmessagerr.r4rEsz#InvalidPyTorchVersionError.__init__)rVr __qualname____doc__r __classcell__r.r.rr4r?sc@seZdZdZdS)rz< Could not import APIs from an optional dependency. N)rVrrrr.r.r.r4rJsFr)zCallable[..., bool]ztuple[Any, bool]) rversionversion_checkerrr descriptor version_argsallow_namespace_pkgas_typer+c sddd}|rd|d|} n d|} zHt|} t|} |s`t| dddkoVt| d} | r`t|rnt| |} Wn.tk r} z| j| }W5d} ~ XYn4X|r|| ||r| dfS|s|| |r| dfS|| |r dkr d |d |d |jd 7|r d |d7Gfddd}dkrH|dfSGfddd|}|dfS)a Imports an optional module specified by `module` string. Any importing related exceptions will be stored, and exceptions raise lazily when attempting to use the failed-to-import module. Args: module: name of the module to be imported. version: version string used by the version_checker. version_checker: a callable to check the module version, Defaults to monai.utils.min_version. name: a non-module attribute (such as method/class) to import from the imported module. descriptor: a format string for the final error message when using a not imported module. version_args: additional parameters to the version checker. allow_namespace_pkg: whether importing a namespace package is allowed. Defaults to False. as_type: there are cases where the optionally imported object is used as a base class, or a decorator, the exceptions should raise accordingly. The current supported values are "default" (call once to raise), "decorator" (call the constructor and the second call to raise), and anything else will return a lazy class that can be used as a base class (call the constructor to raise). Returns: The imported module and a boolean flag indicating whether the import is successful. Examples:: >>> torch, flag = optional_import('torch', '1.1') >>> print(torch, flag) True >>> the_module, flag = optional_import('unknown_module') >>> print(flag) False >>> the_module.method # trying to access a module which is not imported OptionalImportError: import unknown_module (No module named 'unknown_module'). >>> torch, flag = optional_import('torch', '42', exact_version) >>> torch.nn # trying to access a module for which there isn't a proper version imported OptionalImportError: import torch (requires version '42' by 'exact_version'). >>> conv, flag = optional_import('torch.nn.functional', '1.0', name='conv1d') >>> print(conv) >>> conv, flag = optional_import('torch.nn.functional', '42', name='conv1d') >>> conv() # trying to use a function from the not successfully imported module (due to unmatched version) OptionalImportError: from torch.nn.functional import conv1d (requires version '42' by 'min_version'). Nr7zfrom z import zimport __file__rfTz (requires ' z' by 'z')z ()cs:eZdZfddZddZddZddZd d Zd S) z#optional_import.._LazyRaisecs:ddd}dkr&t||_nt||_dS)Nr-zG For details about installing the optional dependencies, please visit:z^ https://docs.monai.io/en/latest/installation.html#installing-the-recommended-dependencies)r _exceptionrn)rr_kwargsZ _default_msgrttbr.r4rs z,optional_import.._LazyRaise.__init__cSs |jdSza Raises: OptionalImportError: When you call this method. Nr)rrrr.r.r4 __getattr__sz/optional_import.._LazyRaise.__getattr__c_s |jdSrr)rrrr.r.r4__call__sz,optional_import.._LazyRaise.__call__cSs |jdSrr)rr3r.r.r4 __getitem__sz/optional_import.._LazyRaise.__getitem__cSs |jdSrr)rr.r.r4__iter__sz,optional_import.._LazyRaise.__iter__N)rVrrrrrrrr.rr.r4 _LazyRaises  rr)FcseZdZfddZZS)z!optional_import.._LazyClscstds|jdS)N decorator)rr startswithr)rrrw)rrr.r4rs  z*optional_import.._LazyCls.__init__)rVrrrrr.)rrr4_LazyClssr) __import__r rXrUAssertionErrorrroformatrV)rrrrrrrrrZ exception_strZ actual_cmdpkgr is_namespaceZimport_exceptionrrr.)rrtrr4rPs>8  !  r)pkg_namerr raise_errorr+csfdd}|S)a Decorator function to check the required package installation. Args: pkg_name: required package name, like: "itk", "nibabel", etc. version: required version string used by the version_checker. version_checker: a callable to check the module version, defaults to `monai.utils.min_version`. raise_error: if True, raise `OptionalImportError` error if the required package is not installed or the version doesn't match requirement, if False, print the error in a warning. csFt|t}|r|n|jtfdd}|r<|S||_|S)NcsDtd\}}|s:dd}r0t|n t|||S)N)rrrzrequired package `z<` is not installed or the version doesn't match requirement.)rrr~r)argsrw_haserr_msg)call_objrrrrr.r4_wrappers   z1require_pkg.._decorator.._wrapper)r:r rr)rYis_funcrrrrr)rr4 _decorators  zrequire_pkg.._decoratorr.)rrrrrr.rr4rs!NOT INSTALLED or UNKNOWN VERSION.cCs$t|\}}|r t|dr |jS|S)zN Try to load package and get version. If not found, return `default`. r)rrUr)Zdep_namer)depZhas_depr.r.r4r s cCs"tddtjdddDS)zT Returns: tuple of ints represents the pytorch major/minor version. css|]}t|VqdSrrrr.r.r4r sz*get_torch_version_tuple..r-NrL)rtorchrrr.r.r.r4r!sz/tuple[Iterable[int | str], Iterable[int | str]])lhsrhsr+cCsXddddd}|ddd}|ddd}t||d }t||d }||fS) z$ Parse the version strings. r=z int | str)valr+cSsT|}z.td|}|dk r2|d}t|WS|WStk rN|YSXdS)Nz (\d+)(.*)r)r>r groupsrEr;)rrr.r.r4 _try_casts   z%parse_version_strs.._try_cast+rIrr-)rmap)rrrlhs_rhs_r.r.r4parse_version_strss  rcCst|t|}}tddd\}}|rbz tt|j||j|kWS|jjk r`YdSXt||\}}t||D]@\}}||krzt |t rt |t r||kS||kSqzdS)a Returns True if version `lhs` is earlier or equal to `rhs`. Args: lhs: version name to compare with `rhs`, return True if earlier or equal to `rhs`. rhs: version name to compare with `lhs`, return True if later or equal to `lhs`. pkg_resources packagingrrT r=rrr&rVersionInvalidVersionrzipr:rErrZpkginghas_verrrlrr.r.r4r")s   cCst|t|}}tddd\}}|rbz tt|j||j|kWS|jjk r`YdSXt||\}}t||D]@\}}||krzt |t rt |t r||kS||kSqzdS)a Returns True if version `lhs` is later or equal to `rhs`. Args: lhs: version name to compare with `rhs`, return True if later or equal to `rhs`. rhs: version name to compare with `lhs`, return True if earlier or equal to `lhs`. rrrTrrr.r.r4r#Es   z str | None)majorminorpatchcurrent_ver_stringr+c Csz|dkr&tjdd}|r |ntj}tddd\}}|r`|d|||f||kWS|dd d dd }t|d kr|d g7}qz|dd \}} } Wn(t t t fk rt \}} d } YnXt |t | f} t |t |f} | | kr| | kSd | kpd| k} d }z$td| }|rFt |}Wn t t t fk rhd} YnXt |}||kr||kS| rdSdS)aJ Compute whether the current pytorch version is after or equal to the specified version. The current system pytorch version is determined by `torch.__version__` or via system environment variable `PYTORCH_VER`. Args: major: major version number to be compared with minor: minor version number to be compared with patch: patch version number to be compared with current_ver_string: if None, `torch.__version__` will be used. Returns: True if the current pytorch version is greater than or equal to the specified version. NZ PYTORCH_VERr7rZ parse_versionrr-rrIrr6rarcz\d+TF)osenvironrDrrrrrrMAttributeErrorr; TypeErrorr!rElowerresearchgroup)rrrrZ_env_varverrpartsZc_majorZc_minorZc_patchZc_mnmn is_prereleaseZc_pZp_regr.r.r4r$`s@&       )r%T)Tr_)r7)r7)r)rN); __future__rr? functoolsrrrrhr~collections.abcrrrrrr importlibr pkgutilr pydocr r typesr rtypingrrrrrrDrun_evalr}allow_missing_referenceZOPTIONAL_IMPORT_MSG_FMT__all__rrrrrrrrrrrmrrrr lru_cacher!rr"r#r$r.r.r.r4 s     S9    '