o  iV@s`dZddlmZddlZddlmZmZddlmZm Z m Z m Z m Z ddl mZmZddlZddlZddlmZmZddlmZdd lmZdd lmZmZmZdd lmZm Z m!Z!dd l"m#Z#dd l$m%Z%gdZ&edZ'    d2d3ddZ(    d4d5d&d'Z)Gd(d)d)eeZ*Gd*d+d+eZ+Gd,d-d-e+eZ,Gd.d/d/e*e+Z-Gd0d1d1e+Z.dS)6z: A collection of generic interfaces for MONAI transforms. ) annotationsN)ABCabstractmethod)Callable GeneratorHashableIterableMapping)AnyTypeVar)config transforms)KeysCollection) MetaTensor) LazyTraitRandomizableTrait ThreadUnsafe)MAX_SEED ensure_tuplefirst)TransformBackends) MONAIEnvVars)rapply_transform Randomizable LazyTransformRandomizableTransform Transform MapTransform ReturnTypeF transformCallable[..., ReturnType]datar unpack_parametersboollazy bool | None overrides dict | None logger_name bool | strreturncCshddlm}||||||}t|tr%|r%t|tr!||d|iS||St|tr0|||dS||S)a% Perform a transform 'transform' on 'data', according to the other parameters specified. If `data` is a tuple and `unpack_parameters` is True, each parameter of `data` is unpacked as arguments to `transform`. Otherwise `data` is considered as single argument to `transform`. If 'lazy' is True, this method first checks whether it can execute this method lazily. If it can't, it will ensure that all pending lazy transforms on 'data' are applied before applying this 'transform' to it. If 'lazy' is True, and 'overrides' are provided, those overrides will be applied to the pending operations on 'data'. See ``Compose`` for more details on lazy resampling, which is an experimental feature for 1.2. Please note, this class is function is designed to be called by ``apply_transform``. In general, you should not need to make specific use of it unless you are implementing pipeline execution mechanisms. Args: transform: a callable to be used to transform `data`. data: the tensorlike or dictionary of tensorlikes to be executed on unpack_parameters: whether to unpack parameters for `transform`. Defaults to False. lazy: whether to enable lazy evaluation for lazy transforms. If False, transforms will be carried out on a transform by transform basis. If True, all lazy transforms will be executed by accumulating changes and resampling as few times as possible. See the :ref:`Lazy Resampling topic for more information about lazy resampling. overrides: this optional parameter allows you to specify a dictionary of parameters that should be overridden when executing a pipeline. These each parameter that is compatible with a given transform is then applied to that transform before it is executed. Note that overrides are currently only applied when :ref:`Lazy Resampling` is enabled for the pipeline or a given transform. If lazy is False they are ignored. Currently supported args are: {``"mode"``, ``"padding_mode"``, ``"dtype"``, ``"align_corners"``, ``"resample_mode"``, ``device``}. logger_name: this optional parameter allows you to specify a logger by name for logging of pipeline execution. Setting this to False disables logging. Setting it to True enables logging to the default loggers. Setting a string overrides the logger name to which logging is performed. Returns: ReturnType: The return type of `transform`. r)!apply_pending_transforms_in_orderr$)r$) monai.transforms.lazy.functionalr+ isinstancetupler)rr!r"r$r&r(r+r/\/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/transforms/transform.py_apply_transform.s - r1T map_items bool | int unpack_items log_statslist[Any] | ReturnTypec sXz/t|tr t|n|t|ttfr&dkr&fdd|DWSt|WSty}zptr<durtt j j stt rWt j jjdddn t j jjdddtj}|dtjdt|ttfr}|d}ddfd d } t|tr|D] \} } | | | dqn| |dtd|d}~ww)a Transform `data` with `transform`. If `data` is a list or tuple and `map_data` is True, each item of `data` will be transformed and this method returns a list of outcomes. otherwise transform will be applied once with `data` as the argument. Args: transform: a callable to be used to transform `data`. data: an object to be transformed. map_items: controls whether to apply a transformation to each item in `data`. If `data` is a list or tuple, it can behave as follows: - Defaults to True, which is equivalent to `map_items=1`, meaning the transformation will be applied to the first level of items in `data`. - If an integer is provided, it specifies the maximum level of nesting to which the transformation should be recursively applied. This allows treating multi-sample transforms applied after another multi-sample transform while controlling how deep the mapping goes. unpack_items: whether to unpack parameters using `*`. Defaults to False. log_stats: log errors when they occur in the processing pipeline. By default, this is set to False, which disables the logger for processing pipeline errors. Setting it to None or True will enable logging to the default logger name. Setting it to a string specifies the logger to which errors should be logged. lazy: whether to execute in lazy mode or not. See the :ref:`Lazy Resampling topic for more information about lazy resampling. Defaults to None. overrides: optional overrides to apply to transform parameters. This parameter is ignored unless transforms are being executed lazily. See the :ref:`Lazy Resampling topic for more details and examples of its usage. Raises: Exception: When ``transform`` raises an exception. Returns: Union[List[ReturnType], ReturnType]: The return type of `transform` or a list thereof. rc s$g|]}t|dqS))r).0item)r$r5 map_items_r&rr4r/r0 sz#apply_transform..F) data_shape value_rangename)r<r=z === Transform input info -- z ===Dataprefix str | Nonecs8t|tjtjfr|dd|ddS|d|ddS)NT)imgr<r=r@)rB data_valuer@)r-npndarraytorchTensorr!r@) datastatsr/r0 _log_statssz#apply_transform.._log_statsrH)r!zapplying transform N)r?)r@rA)r-r#intlistr.r1 Exceptionrdebugr composeComposestrZutilityarray DataStatslogging getLoggerZ _logger_nameerrortype__name__dictitems RuntimeError) rr!r2r4r5r$r&eloggerrJkvr/)rIr$r5r:r&rr4r0res6*    rc@s:eZdZUdZejZded<ddd d Z dddZ dS)ra7 An interface for handling random state locally, currently based on a class variable `R`, which is an instance of `np.random.RandomState`. This provides the flexibility of component-specific determinism without affecting the global states. It is recommended to use this API with :py:class:`monai.data.DataLoader` for deterministic behaviour of the preprocessing pipelines. This API is not thread-safe. Additionally, deepcopying instance of this class often causes insufficient randomness as the random states will be duplicated. znp.random.RandomStateRNseed int | Nonestatenp.random.RandomState | Noner*cCs|dur"tt|ttjfst|n|}|t}tj||_ |S|dur=t|tjjs8t dt |j d||_ |Stj|_ |S)a Set the random state locally, to control the randomness, the derived classes should use :py:attr:`self.R` instead of `np.random` to introduce random factors. Args: seed: set the random state with an integer seed. state: set the random state with a `np.random.RandomState` object. Raises: TypeError: When ``state`` is not an ``Optional[np.random.RandomState]``. Returns: a Randomizable instance. Nz5state must be None or a np.random.RandomState but is .) rDint64r-rKintegeridrrandom RandomStater` TypeErrorrWrX)selfrarc_seedr/r/r0set_random_states" zRandomizable.set_random_stater!r NonecCtd|jjd)a Within this method, :py:attr:`self.R` should be used, instead of `np.random`, to introduce random factors. all :py:attr:`self.R` calls happen here so that we have a better chance to identify errors of sync the random state. This method can generate the random factors based on properties of the input data. Raises: NotImplementedError: When the subclass does not override this method. Subclass  must implement this method.NotImplementedError __class__rXrlr!r/r/r0 randomizes zRandomizable.randomize)NN)rarbrcrdr*rr!r r*ro) rX __module__ __qualname____doc__rDrirjr`__annotations__rnrwr/r/r/r0rs   rc@s,eZdZUdZgZded<ed ddZdS) ra: An abstract class of a ``Transform``. A transform is callable that processes ``data``. It could be stateful and may modify ``data`` in place, the implementation should be aware of: #. thread safety when mutating its own states. When used from a multi-process context, transform's instance variables are read-only. thread-unsafe transforms should inherit :py:class:`monai.transforms.ThreadUnsafe`. #. ``data`` content unused by this transform may still be used in the subsequent transforms in a composed transform. #. storing too much information in ``data`` may cause some memory issue or IPC sync issue, especially in the multi-processing environment of PyTorch DataLoader. See Also :py:class:`monai.transforms.Compose` zlist[TransformBackends]backendr!r cCrp)a ``data`` is an element which often comes from an iteration over an iterable, such as :py:class:`torch.utils.data.Dataset`. This method should return an updated version of ``data``. To simplify the input validations, most of the transforms assume that - ``data`` is a Numpy ndarray, PyTorch Tensor or string, - the data shape can be: #. string data without shape, `LoadImage` transform expects file paths, #. most of the pre-/post-processing transforms expect: ``(num_channels, spatial_dim_1[, spatial_dim_2, ...])``, except for example: `AddChannel` expects (spatial_dim_1[, spatial_dim_2, ...]) - the channel dimension is often not omitted even if number of channels is one. This method can optionally take additional arguments to help execute transformation operation. Raises: NotImplementedError: When the subclass does not override this method. rqrrrsrvr/r/r0__call__szTransform.__call__N)r!r )rXryrzr{r}r|rr~r/r/r/r0rs  rc@sDeZdZdZd dddZeddZejdd dZed d Zd S)rz An implementation of functionality for lazy transforms that can be subclassed by array and dictionary transforms to simplify implementation of new lazy transforms. Fr$r%cC.|durt|tstdt|||_dSNz#lazy must be a bool but is of type r-r#rkrW_lazyrlr$r/r/r0__init__2s  zLazyTransform.__init__cCs|jS)N)rrlr/r/r0r$8szLazyTransform.lazycCrrrrr/r/r0r$<s  cCsdS)NFr/rr/r/r0requires_current_dataCsz#LazyTransform.requires_current_dataNF)r$r%) rXryrzr{rpropertyr$setterrr/r/r/r0r,s   rc@s&eZdZdZdddd ZdddZdS)rag An interface for handling random state locally, currently based on a class variable `R`, which is an instance of `np.random.RandomState`. This class introduces a randomized flag `_do_transform`, is mainly for randomized data augmentation transforms. For example: .. code-block:: python from monai.transforms import RandomizableTransform class RandShiftIntensity100(RandomizableTransform): def randomize(self): super().randomize(None) self._offset = self.R.uniform(low=0, high=100) def __call__(self, img): self.randomize() if not self._do_transform: return img return img + self._offset transform = RandShiftIntensity() transform.set_random_state(seed=0) print(transform(10)) ?Tprobfloat do_transformr#cCs||_tt|dd|_dS)Ngr) _do_transformminmaxr)rlrrr/r/r0rdszRandomizableTransform.__init__r!r r*rocCs|j|jk|_dS)a^ Within this method, :py:attr:`self.R` should be used, instead of `np.random`, to introduce random factors. all :py:attr:`self.R` calls happen here so that we have a better chance to identify errors of sync the random state. This method can generate the random factors based on properties of the input data. N)r`randrrrvr/r/r0rwhs zRandomizableTransform.randomizeN)rT)rrrr#rx)rXryrzr{rrwr/r/r/r0rHs rcsTeZdZdZddZddfd d Zd dZeddZdddZ dddZ Z S)raV A subclass of :py:class:`monai.transforms.Transform` with an assumption that the ``data`` input of ``self.__call__`` is a MutableMapping such as ``dict``. The ``keys`` parameter will be used to get and set the actual data item to transform. That is, the callable of this transform should follow the pattern: .. code-block:: python def __call__(self, data): for key in self.keys: if key in data: # update output data with some_transform_function(data[key]). else: # raise exception unless allow_missing_keys==True. return data Raises: ValueError: When ``keys`` is an empty iterable. TypeError: When ``keys`` type is not in ``Union[Hashable, Iterable[Hashable]]``. cOsBtjrt|jtjd|_t|drt|jtj j |_t |S)Npostinverse) r USE_META_DICTr attach_hookr~r call_updatehasattrrInvertibleTransforminverse_updater__new__)clsargskwargsr/r/r0rs   zMapTransform.__new__Fkeysrallow_missing_keysr#r*rocsXtt||_||_|jstd|jD]}t|ts)tdt |j dqdS)Nzkeys must be non empty.z:keys must be one of (Hashable, Iterable[Hashable]) but is re) superrrrr ValueErrorr-rrkrWrX)rlrrkeyrur/r0rs    zMapTransform.__init__cCst|tttfs |Sd}t|tr|gd}}|r t|dts(|r&|dS|Sdd|D}t|D] \}}|D]}t||tsCq9tj||t|tj d||<q9q3|rZ|dS|S)z This function is to be called after every `self.__call__(data)`, update `data[key_transforms]` and `data[key_meta_dict]` using the content from MetaTensor `data[key]`, for MetaTensor backward compatibility 0.9.0. FTrcSsg|]}t|qSr/)rY)r8xr/r/r0r;sz,MapTransform.call_update..)t) r-rLr.r enumeraterr sync_meta_infoInvertD)rlr!is_dictZlist_didxZdict_ir^r/r/r0rs   zMapTransform.call_updatecCrp)a ``data`` often comes from an iteration over an iterable, such as :py:class:`torch.utils.data.Dataset`. To simplify the input validations, this method assumes: - ``data`` is a Python dictionary, - ``data[key]`` is a Numpy ndarray, PyTorch Tensor or string, where ``key`` is an element of ``self.keys``, the data shape can be: #. string data without shape, `LoadImaged` transform expects file paths, #. most of the pre-/post-processing transforms expect: ``(num_channels, spatial_dim_1[, spatial_dim_2, ...])``, except for example: `AddChanneld` expects (spatial_dim_1[, spatial_dim_2, ...]) - the channel dimension is often not omitted even if number of channels is one. Raises: NotImplementedError: When the subclass does not override this method. returns: An updated dictionary version of ``data`` by applying the transform. rqrrrsrvr/r/r0r~szMapTransform.__call__r!Mapping[Hashable, Any]extra_iterablesIterable | Nonercgsz|p dgt|jg}t|jg|RD]%^}}||vr*|r&|ft|n|Vq|js:td|d|jjdqdS)a[ Iterate across keys and optionally extra iterables. If key is missing, exception is raised if `allow_missing_keys==False` (default). If `allow_missing_keys==True`, key is skipped. Args: data: data that the transform will be applied to extra_iterables: anything else to be iterated through NzKey `z` of transform `z8` was missing in the data and allow_missing_keys==False.)lenrzipr.rKeyErrorrurX)rlr!rZex_itersrZ _ex_itersr/r/r0 key_iterators zMapTransform.key_iteratordict[Hashable, Any]cCst||dS)z Get the first available key of `self.keys` in the input `data` dictionary. If no available key, return an empty tuple `()`. Args: data: data that the transform will be applied to. r/)rrrvr/r/r0 first_keys zMapTransform.first_keyr)rrrr#r*ro)r!rrrr*r)r!r) rXryrzr{rrrrr~rr __classcell__r/r/rr0rts    r)FFNF)rr r!r r"r#r$r%r&r'r(r)r*r)TFFNN)rr r!r r2r3r4r#r5r)r$r%r&r'r*r6)/r{ __future__rrTabcrrcollections.abcrrrrr typingr r numpyrDrFmonair r monai.configrmonai.data.meta_tensorrmonai.transforms.traitsrrr monai.utilsrrrmonai.utils.enumsrmonai.utils.miscr__all__rr1rrrrrrr/r/r/r0sB       : R=8,