U
    Ph                 n   @  s  d Z ddlmZ ddlZddlmZmZmZ ddlm	Z	 ddl
mZmZmZ ddlZddlZddlmZmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ ddlmZmZ ddl m!Z!m"Z"m#Z# ddl$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZA ddlBmCZCmDZD ddlEmFZF ddlGmHZHmIZI ddlJmKZKmLZLmMZM ddlNmOZO 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/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddgnZPeKQ ZRG dd= d=e!ZSG dd de!ZTG dd4 d4e!ZUG dd] d]e!ZVG ddZ dZe!ZWG ddf dfe!eZXG dd de!ZYG ddx dxe!eZZG dd7 d7e!Z[G ddr dre!Z\G ddl dle!Z]G ddu due!Z^G dd| d|e!eZ_G dd1 d1e!Z`G dd` d`e!ZaG ddK dKe!ZbG ddi die!ZcG dd. d.e!ZdG ddc dce!ZeG dd( d(e!ZfG dd" d"e!ZgG ddG dGe!eZhG ddT dTehe#ZiG ddD dDe!ZjG dd: d:e!eZkG dd de!eZlG dd% d%e!ZmG dd de"e!ZnG dd{ d{e!ZoG ddW dWe!eZpG ddJ dJe!ZqG dd> d>e!ZrG ddm dme!ZsG dd) d)e!ZtG ddN dNe!eZuG dd de!ZvG ddA dAe!ZwG ddQ dQe!e#Zxex ZyZzew Z{Z|eS Z}Z~eT ZZeU ZZeW ZZeV ZZeX ZZeY ZZeZ ZZe[ ZZe\ ZZe] ZZe^ ZZe_ ZZe` ZZea ZZec ZZed ZZee ZZef ZZeg ZZeh ZZej ZZek ZZel ZZem ZZen ZZeo ZZep ZZei ZZeq ZZer ZZes ZZet ZZeu ZZev ZZeb ZZdS )z
A collection of dictionary-based wrappers around the "vanilla" transforms for utility functions
defined in :py:class:`monai.transforms.utility.array`.

Class names are ended with 'd' to denote dictionary-based transforms.
    )annotationsN)CallableHashableMapping)deepcopy)AnySequencecast)	DtypeLikeKeysCollection)NdarrayOrTensor)MetaObj
MetaTensor)no_collation)InvertibleTransform)MultiSampleTraitRandomizableTrait)MapTransformRandomizableRandomizableTransform)AddCoordinateChannelsAddExtremePointsChannelAsChannelLast
CastToTypeClassesToIndices(ConvertToMultiChannelBasedOnBratsClassesCuCIM	DataStatsEnsureChannelFirst
EnsureTypeFgBgToIndicesIdentityImageFilterIntensityStatsLabelToMaskLambdaMapLabelValueRemoveRepeatedChannelRepeatChannelSimulateDelaySplitDim
SqueezeDimToCupyToDeviceToNumpyToPILTorchVisionToTensor	Transpose)extreme_points_to_imageget_extreme_points)concatenate)ensure_tupleensure_tuple_rep)PostFix	TraceKeysTransformBackends)convert_to_dst_typeAddCoordinateChannelsDAddCoordinateChannelsDictAddCoordinateChannelsdAddExtremePointsChannelDAddExtremePointsChannelDictAddExtremePointsChanneldAsChannelLastDAsChannelLastDictAsChannelLastdCastToTypeDCastToTypeDictCastToTypedConcatItemsDConcatItemsDictConcatItemsd)ConvertToMultiChannelBasedOnBratsClassesD,ConvertToMultiChannelBasedOnBratsClassesDict)ConvertToMultiChannelBasedOnBratsClassesd
CopyItemsDCopyItemsDict
CopyItemsdCuCIMdCuCIMD	CuCIMDict
DataStatsDDataStatsDict
DataStatsdDeleteItemsDDeleteItemsDictDeleteItemsdEnsureChannelFirstDEnsureChannelFirstDictEnsureChannelFirstdEnsureTypeDEnsureTypeDictEnsureTypedFgBgToIndicesDFgBgToIndicesDictFgBgToIndicesd	IdentityDIdentityDict	IdentitydIntensityStatsdIntensityStatsDIntensityStatsDictImageFilterdLabelToMaskDLabelToMaskDictLabelToMaskdLambdaD
LambdaDictLambdadMapLabelValueDMapLabelValueDictMapLabelValuedFlattenSubKeysdFlattenSubKeysDFlattenSubKeysDict
RandCuCIMd
RandCuCIMDRandCuCIMDictRandImageFilterdRandLambdaDRandLambdaDictRandLambdadRandTorchVisionDRandTorchVisionDictRandTorchVisiondRemoveRepeatedChannelDRemoveRepeatedChannelDictRemoveRepeatedChanneldRepeatChannelDRepeatChannelDictRepeatChanneldSelectItemsDSelectItemsDictSelectItemsdSimulateDelayDSimulateDelayDictSimulateDelayd	SplitDimDSplitDimDict	SplitDimdSqueezeDimDSqueezeDimDictSqueezeDimdToCupyD
ToCupyDictToCupyd	ToDeviced	ToDeviceDToDeviceDictToNumpyDToNumpyDictToNumpydToPILD	ToPILDictToPILd	ToTensorDToTensorDict	ToTensordTorchVisionDTorchVisionDictTorchVisiond
TransposedTransposeDict
TransposeDClassesToIndicesdClassesToIndicesDClassesToIndicesDictc                      sB   e Zd ZdZejZddddd fddZd	d
dddZ  ZS )re   zL
    Dictionary-based wrapper of :py:class:`monai.transforms.Identity`.
    Fr   boolNonekeysallow_missing_keysreturnc                   s   t  || t | _dS )z
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            allow_missing_keys: don't raise exception if key is missing.

        N)super__init__r!   identityselfr   r   	__class__ X/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/transforms/utility/dictionary.pyr      s    zIdentityd.__init__"Mapping[Hashable, NdarrayOrTensor]dict[Hashable, NdarrayOrTensor]datar   c                 C  s.   t |}| |D ]}| || ||< q|S N)dictkey_iteratorr   r   r   dkeyr   r   r   __call__   s    zIdentityd.__call__)F)	__name__
__module____qualname____doc__r!   backendr   r   __classcell__r   r   r   r   re      s   c                      sD   e Zd ZdZejZdddddd fd	d
ZdddddZ  ZS )rD   zQ
    Dictionary-based wrapper of :py:class:`monai.transforms.AsChannelLast`.
    r   Fr   intr   r   )r   channel_dimr   r   c                   s   t  || t|d| _dS )aY  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            channel_dim: which dimension of input image is the channel, default is the first dimension.
            allow_missing_keys: don't raise exception if key is missing.
        )r   N)r   r   r   	converter)r   r   r   r   r   r   r   r      s    zAsChannelLastd.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r   r   r   r   r   r      s    zAsChannelLastd.__call__)r   F)	r   r   r   r   r   r   r   r   r   r   r   r   r   rD      s   c                      sD   e Zd ZdZejZdddddd fd	d
ZdddddZ  ZS )r\   zV
    Dictionary-based wrapper of :py:class:`monai.transforms.EnsureChannelFirst`.
    TFNr   r   r   )r   strict_checkr   r   c                   s    t  || t||d| _dS )a  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            strict_check: whether to raise an error when the meta information is insufficient.
            allow_missing_keys: don't raise exception if key is missing.
            channel_dim: This argument can be used to specify the original channel dimension (integer) of the input array.
                It overrides the `original_channel_dim` from provided MetaTensor input.
                If the input array doesn't have a channel dim, this value should be ``'no_channel'``.
                If this is set to `None`, this class relies on `img` or `meta_dict` to provide the channel dimension.
        )r   r   N)r   r   r   adjuster)r   r   r   r   r   r   r   r   r      s    zEnsureChannelFirstd.__init__Mapping[Hashable, torch.Tensor]dict[Hashable, torch.Tensor]r   c                 C  sL   t |}| |D ]4}t|| tr.|| jnd }| || |||< q|S r   )r   r   
isinstancer   metar   )r   r   r   r   	meta_dictr   r   r   r     s
    zEnsureChannelFirstd.__call__)TFN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r\      s        c                      sD   e Zd ZdZejZdddddd fdd	Zd
ddddZ  ZS )r   zQ
    Dictionary-based wrapper of :py:class:`monai.transforms.RepeatChannel`.
    Fr   r   r   r   r   repeatsr   r   c                   s   t  || t|| _dS a2  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            repeats: the number of repetitions for each element.
            allow_missing_keys: don't raise exception if key is missing.
        N)r   r   r(   repeaterr   r   r   r   r   r   r   r     s    zRepeatChanneld.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r   r   r   r   r   r      s    zRepeatChanneld.__call__)F)	r   r   r   r   r(   r   r   r   r   r   r   r   r   r     s   c                      sD   e Zd ZdZejZdddddd fdd	Zd
ddddZ  ZS )r   zY
    Dictionary-based wrapper of :py:class:`monai.transforms.RemoveRepeatedChannel`.
    Fr   r   r   r   r   c                   s   t  || t|| _dS r   )r   r   r'   r   r   r   r   r   r   .  s    zRemoveRepeatedChanneld.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r   r   r   r   9  s    zRemoveRepeatedChanneld.__call__)F)	r   r   r   r   r'   r   r   r   r   r   r   r   r   r   '  s   c                
      sH   e Zd ZejZddddddddd	d
 fddZdddddZ  ZS )r   Nr   TFr   zSequence[str] | Noner   r   r   )r   output_postfixesdimkeepdimupdate_metalist_outputr   r   c                   sH   t  || || _t|||| _|| _| jdkrD| jdk	rDtddS )a'  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            output_postfixes: the postfixes to construct keys to store split data.
                for example: if the key of input data is `pred` and split 2 classes, the output
                data keys will be: pred_(output_postfixes[0]), pred_(output_postfixes[1])
                if None, using the index number: `pred_0`, `pred_1`, ... `pred_N`.
            dim: which dimension of input image is the channel, default to 0.
            keepdim: if `True`, output will have singleton in the split dimension. If `False`, this
                dimension will be squeezed.
            update_meta: if `True`, copy `[key]_meta_dict` for each output and update affine to
                reflect the cropped image
            list_output: it `True`, the output will be a list of dictionaries with the same keys as original.
            allow_missing_keys: don't raise exception if key is missing.
        NzG`output_postfixes` should not be provided when `list_output` is `True`.)r   r   r   r*   splitterr   
ValueError)r   r   r   r   r   r   r   r   r   r   r   r   C  s    zSplitDimd.__init__r   zAdict[Hashable, torch.Tensor] | list[dict[Hashable, torch.Tensor]]r   c                   s>  t | tt }jrg } fdd|D }t| D ]H}t t||}t  t|D ]}t | ||< qh|	| q@|S |D ]}
 | }	jd krttt|	nj}
t|
t|	krtdt|
 dt|	 dt|	D ]<\}}| d|
|  }| kr.td| d| |< qq S )Nc                   s   g | ]}  | qS r   )r   .0r   r   r   r   r   
<listcomp>l  s     z&SplitDimd.__call__.<locals>.<listcomp>z-count of splits must match output_postfixes, z != ._z input data already contains key )r   listsetr   r   zipr   
differencer   appendr   r   rangelenr   	enumerateRuntimeError)r   r   all_keysoutputresultsrownew_dictkr   rets	postfixesirZ	split_keyr   r   r   r   d  s,     
zSplitDimd.__call__)Nr   TTFF)r   r   r   r*   r   r   r   r   r   r   r   r   r   @  s         "!c                   @  sB   e Zd ZdZejZejdfddddddd	Zd
ddddZ	dS )rG   zN
    Dictionary-based wrapper of :py:class:`monai.transforms.CastToType`.
    Fr   ;Sequence[DtypeLike | torch.dtype] | DtypeLike | torch.dtyper   r   )r   dtyper   r   c                 C  s,   t | || t|t| j| _t | _dS )a  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            dtype: convert image to this data type, default is `np.float32`.
                it also can be a sequence of dtypes or torch.dtype,
                each element corresponds to a key in ``keys``.
            allow_missing_keys: don't raise exception if key is missing.

        N)r   r   r7   r   r   r   r   r   )r   r   r   r   r   r   r   r     s    zCastToTyped.__init__r   r   r   c                 C  s:   t |}| || jD ]\}}| j|| |d||< q|S )N)r   r   r   r   r   r   r   r   r   r   r   r   r   r     s    zCastToTyped.__call__N)
r   r   r   r   r   r   npfloat32r   r   r   r   r   r   rG     s   c                	      sZ   e Zd ZdZejZdddddd	dd
d fddZdddddZdddddZ  Z	S )r   zL
    Dictionary-based wrapper of :py:class:`monai.transforms.ToTensor`.
    NTFr   ztorch.dtype | Noneztorch.device | str | Noner   bool | Noner   )r   r   devicewrap_sequence
track_metar   r   c                   s$   t  || t||||d| _dS )a;  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            dtype: target data content type to convert, for example: torch.float, etc.
            device: specify the target device to put the Tensor data.
            wrap_sequence: if `False`, then lists will recursively call this function, default to `True`.
                E.g., if `False`, `[1, 2]` -> `[tensor(1), tensor(2)]`, if `True`, then `[1, 2]` -> `tensor([1, 2])`.
            track_meta: if `True` convert to ``MetaTensor``, otherwise to Pytorch ``Tensor``,
                if ``None`` behave according to return value of py:func:`monai.data.meta_obj.get_track_meta`.
            allow_missing_keys: don't raise exception if key is missing.

        )r   r  r  r  N)r   r   r1   r   )r   r   r   r  r  r  r   r   r   r   r     s    zToTensord.__init__r   r   r   c                 C  s:   t |}| |D ]"}| || ||< | || q|S r   )r   r   r   push_transformr   r   r   r   r     s
    zToTensord.__call__c                 C  s>   t |}| |D ]&}| || t }||| ||< q|S r   )r   r   pop_transformr.   )r   r   r   r   inverse_transformr   r   r   inverse  s    zToTensord.inverse)NNTNF)
r   r   r   r   r1   r   r   r   r  r   r   r   r   r   r     s         c                
      sL   e Zd ZdZejZddddd	d
dd
dd fddZdddddZ  ZS )r_   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.EnsureType`.

    Ensure the input data to be a PyTorch Tensor or numpy array, support: `numpy array`, `PyTorch Tensor`,
    `float`, `int`, `bool`, `string` and `object` keep the original.
    If passing a dictionary, list or tuple, still return dictionary, list or tuple and recursively convert
    every item to the expected data type if `wrap_sequence=False`.

    Note: Currently, we only convert tensor data to numpy array or scalar number in the inverse operation.

    tensorNTFr   strr   ztorch.device | Noner   r  r   )r   	data_typer   r  r  r  r   r   c                   s6   t  || t|t| j| _t||||d| _dS )a   
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            data_type: target data type to convert, should be "tensor" or "numpy".
            dtype: target data content type to convert, for example: np.float32, torch.float, etc.
                It also can be a sequence of dtype, each element corresponds to a key in ``keys``.
            device: for Tensor data type, specify the target device.
            wrap_sequence: if `False`, then lists will recursively call this function, default to `True`.
                E.g., if `False`, `[1, 2]` -> `[tensor(1), tensor(2)]`, if `True`, then `[1, 2]` -> `tensor([1, 2])`.
            track_meta: whether to convert to `MetaTensor` when `data_type` is "tensor".
                If False, the output data type will be `torch.Tensor`. Default to the return value of `get_track_meta`.
            allow_missing_keys: don't raise exception if key is missing.
        )r  r  r  r  N)r   r   r7   r   r   r   r   r   )r   r   r  r   r  r  r  r   r   r   r   r     s       zEnsureTyped.__init__r   r   r   c                 C  s8   t |}| || jD ]\}}| || |||< q|S r   r   r   r   r   r   r     s    zEnsureTyped.__call__)r	  NNTNF)	r   r   r   r   r   r   r   r   r   r   r   r   r   r_     s         "c                      sF   e Zd ZdZejZddddddd	 fd
dZdddddZ  ZS )r   K
    Dictionary-based wrapper of :py:class:`monai.transforms.ToNumpy`.
    NTFr   r
   r   r   r   r   r  r   r   c                   s    t  || t||d| _dS )a  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            dtype: target data type when converting to numpy array.
            wrap_sequence: if `False`, then lists will recursively call this function, default to `True`.
                E.g., if `False`, `[1, 2]` -> `[array(1), array(2)]`, if `True`, then `[1, 2]` -> `array([1, 2])`.
            allow_missing_keys: don't raise exception if key is missing.
        r   r  N)r   r   r.   r   r   r   r   r  r   r   r   r   r     s    zToNumpyd.__init__Mapping[Hashable, Any]dict[Hashable, Any]r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r   r   r   r   &  s    zToNumpyd.__call__)NTF)	r   r   r   r   r.   r   r   r   r   r   r   r   r   r     s      c                      sF   e Zd ZdZejZddddddd	 fd
dZdddddZ  ZS )r   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.ToCupy`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        dtype: data type specifier. It is inferred from the input by default.
            if not None, must be an argument of `numpy.dtype`, for more details:
            https://docs.cupy.dev/en/stable/reference/generated/cupy.array.html.
        wrap_sequence: if `False`, then lists will recursively call this function, default to `True`.
            E.g., if `False`, `[1, 2]` -> `[array(1), array(2)]`, if `True`, then `[1, 2]` -> `array([1, 2])`.
        allow_missing_keys: don't raise exception if key is missing.
    NTFr   znp.dtype | Noner   r   r  c                   s    t  || t||d| _d S )Nr  )r   r   r,   r   r  r   r   r   r   >  s    zToCupyd.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r   r   r   r   H  s    zToCupyd.__call__)NTF)	r   r   r   r   r,   r   r   r   r   r   r   r   r   r   -  s      
c                      sB   e Zd ZdZejZddddd fddZd	d
dddZ  ZS )r   r  Fr   r   r   r   c                   s   t  || t | _dS )z
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            allow_missing_keys: don't raise exception if key is missing.
        N)r   r   r/   r   r   r   r   r   r   V  s    zToPILd.__init__r  r  r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r   r   r   r   `  s    zToPILd.__call__)F)	r   r   r   r   r/   r   r   r   r   r   r   r   r   r   O  s   
c                      sT   e Zd ZdZejZdddddd fdd	Zd
ddddZdddddZ  Z	S )r   zM
    Dictionary-based wrapper of :py:class:`monai.transforms.Transpose`.
    Fr   Sequence[int] | Noner   r   )r   indicesr   r   c                   s   t  || t|| _d S r   )r   r   r2   	transform)r   r   r  r   r   r   r   r   n  s    zTransposed.__init__r   r   r   c                 C  sb   t |}| |D ]J}| || ||< | jjpFt|| jd d d }| j||d|id q|S )Nr  
extra_info)r   r   r  r  r   ndimr  )r   r   r   r   r  r   r   r   r   r  s     zTransposed.__call__r  r  c                 C  sn   t |}| |D ]V}| ||}t|tj d }t|}t|	 }||| ||< | 
|| q|S )Nr  )r   r   get_most_recent_transformr   arrayr9   
EXTRA_INFOargsortr2   tolistr  )r   r   r   r   r  Zfwd_indicesZinv_indicesr  r   r   r   r  {  s    
zTransposed.inverse)F)
r   r   r   r   r2   r   r   r   r  r   r   r   r   r   r   g  s
   	c                      sB   e Zd ZdZejejgZdddddd fd	d
Zdd Z	  Z
S )rY   z
    Delete specified items from data dictionary to release memory.
    It will remove the key-values and copy the others to construct a new dictionary.
    r   Fr   r
  Sequence[bool] | boolr   )r   sepuse_rer   c                   s(   t  | || _t|t| j| _dS )a  
        Args:
            keys: keys of the corresponding items to delete, can be "A{sep}B{sep}C"
                to delete key `C` in nested dictionary, `C` can be regular expression.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            sep: the separator tag to define nested dictionary keys, default to ".".
            use_re: whether the specified key is a regular expression, it also can be
                a list of bool values, mapping them to `keys`.
        N)r   r   r  r7   r   r   r   )r   r   r  r   r   r   r   r     s    
zDeleteItemsd.__init__c                   sV   ddd fdd t |}tttt | j| jD ]\}} || j||}q4|S )NFr   )r   c                   sL   | d  t | dkr4| dd  |  | < |S  fdd| D S )Nr      c                   s4   i | ],\}}rt  | r*s| kr||qS r   )research)r   r   vr   r   r   r   
<dictcomp>  s          z?DeleteItemsd.__call__.<locals>._delete_item.<locals>.<dictcomp>)r   items)r   r   r   _delete_itemr%  r   r)    s
    z+DeleteItemsd.__call__.<locals>._delete_item)F)	r   r   r	   r   r
  r   r   splitr  )r   r   r   r   r   r   r(  r   r     s
     zDeleteItemsd.__call__)r   Fr   r   r   r   r:   TORCHNUMPYr   r   r   r   r   r   r   r   rY     s   c                   @  s$   e Zd ZdZejejgZdd ZdS )r   z
    Select only specified items from data dictionary to release memory.
    It will copy the selected key-values and construct a new dictionary.
    c                   s    fdd|   D S )Nc                   s   i | ]}| | qS r   r   r   r   r   r   r&    s      z)SelectItemsd.__call__.<locals>.<dictcomp>)r   )r   r   r   r.  r   r     s    zSelectItemsd.__call__N)	r   r   r   r   r:   r,  r-  r   r   r   r   r   r   r     s   c                      sD   e Zd ZdZejejgZddddddd	 fd
dZdd Z	  Z
S )rs   a]  
    If an item is dictionary, it flatten the item by moving the sub-items (defined by sub-keys) to the top level.
    {"pred": {"a": ..., "b", ... }} --> {"a": ..., "b", ... }

    Args:
        keys: keys of the corresponding items to be flatten
        sub_keys: the sub-keys of items to be flatten. If not provided all the sub-keys are flattened.
        delete_keys: whether to delete the key of the items that their sub-keys are flattened. Default to True.
        prefix: optional prefix to be added to the sub-keys when moving to the top level.
            By default no prefix will be added.
    NTr   KeysCollection | Noner   
str | Noner   )r   sub_keysdelete_keysprefixr   c                   s"   t  | || _|| _|| _d S r   )r   r   r1  r2  r3  )r   r   r1  r2  r3  r   r   r   r     s    zFlattenSubKeysd.__init__c                 C  s   t |}| |D ]x}| jd kr,||  n| j}|D ]F}| jrP| j d| n|}||krltd| d|| | ||< q6| jr||= q|S )Nr   'zR' already exists in the top-level keys. Please change `prefix` to avoid duplicity.)r   r   r1  r   r3  r   r2  )r   r   r   r   r1  skZsk_topr   r   r   r     s    
zFlattenSubKeysd.__call__)NTNr+  r   r   r   r   rs     s      c                      sF   e Zd ZdZejZddddddd	 fd
dZdddddZ  ZS )r   zN
    Dictionary-based wrapper of :py:class:`monai.transforms.SqueezeDim`.
    r   TFr   r   r   r   )r   r   r   r   r   c                   s    t  || t||d| _dS )a  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            dim: dimension to be squeezed. Default: 0 (the first dimension)
            update_meta: whether to update the meta info if the input is a metatensor. Default is ``True``.
            allow_missing_keys: don't raise exception if key is missing.
        )r   r   N)r   r   r+   r   )r   r   r   r   r   r   r   r   r     s    zSqueezeDimd.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r   r   r   r     s    zSqueezeDimd.__call__)r   TF)	r   r   r   r   r+   r   r   r   r   r   r   r   r   r     s        c                      sP   e Zd ZdZejZdddd	d	d	d	d
dddd
 fddZdddddZ  ZS )rV   zM
    Dictionary-based wrapper of :py:class:`monai.transforms.DataStats`.
    DataTFNr   r   zSequence[str] | strr  z$Sequence[Callable] | Callable | Noner
  r   r   )
r   r3  r  
data_shapevalue_range
data_valueadditional_infonamer   r   c
           
        s   t  ||	 t|t| j| _t|t| j| _t|t| j| _t|t| j| _t|t| j| _	t|t| j| _
t|d| _dS )a  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            prefix: will be printed in format: "{prefix} statistics".
                it also can be a sequence of string, each element corresponds to a key in ``keys``.
            data_type: whether to show the type of input data.
                it also can be a sequence of bool, each element corresponds to a key in ``keys``.
            data_shape: whether to show the shape of input data.
                it also can be a sequence of bool, each element corresponds to a key in ``keys``.
            value_range: whether to show the value range of input data.
                it also can be a sequence of bool, each element corresponds to a key in ``keys``.
            data_value: whether to show the raw value of input data.
                it also can be a sequence of bool, each element corresponds to a key in ``keys``.
                a typical example is to print some properties of Nifti image: affine, pixdim, etc.
            additional_info: user can define callable function to extract
                additional info from input data. it also can be a sequence of string, each element
                corresponds to a key in ``keys``.
            name: identifier of `logging.logger` to use, defaulting to "DataStats".
            allow_missing_keys: don't raise exception if key is missing.

        )r;  N)r   r   r7   r   r   r3  r  r7  r8  r9  r:  r   printer)
r   r   r3  r  r7  r8  r9  r:  r;  r   r   r   r   r     s    "zDataStatsd.__init__r   r   r   c           
   
   C  s`   t |}| || j| j| j| j| j| jD ]0\}}}}}}}	| || ||||||	||< q*|S r   )	r   r   r3  r  r7  r8  r9  r:  r<  )
r   r   r   r   r3  r  r7  r8  r9  r:  r   r   r   r   ;  s           zDataStatsd.__call__)r6  TTTFNr   F)	r   r   r   r   r   r   r   r   r   r   r   r   r   rV   	  s           &+c                      sD   e Zd ZdZejZdddddd fd	d
ZdddddZ  ZS )r   zQ
    Dictionary-based wrapper of :py:class:`monai.transforms.SimulateDelay`.
            Fr   zSequence[float] | floatr   r   )r   
delay_timer   r   c                   s,   t  || t|t| j| _t | _dS )a  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            delay_time: The minimum amount of time, in fractions of seconds, to accomplish this identity task.
                It also can be a sequence of string, each element corresponds to a key in ``keys``.
            allow_missing_keys: don't raise exception if key is missing.

        N)r   r   r7   r   r   r>  r)   delayer)r   r   r>  r   r   r   r   r   K  s    zSimulateDelayd.__init__r   r   r   c                 C  s:   t |}| || jD ]\}}| j|| |d||< q|S )N)r>  )r   r   r>  r?  )r   r   r   r   r>  r   r   r   r   [  s    zSimulateDelayd.__call__)r=  F)	r   r   r   r   r)   r   r   r   r   r   r   r   r   r   D  s      c                      sL   e Zd ZdZejejgZdddddd	d
 fddZdddddZ	  Z
S )rP   z
    Copy specified items from data dictionary and save with different key names.
    It can copy several items together and copy several times.
    r!  NFr   r   r/  r   r   )r   timesnamesr   r   c                   s   t  || |dk r&td| d| _|dkrH fdd jD nt|}t|t j| krtdt| dt j|  d| _dS )	a  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            times: expected copy times, for example, if keys is "img", times is 3,
                it will add 3 copies of "img" data to the dictionary, default to 1.
            names: the names corresponding to the newly copied data,
                the length should match `len(keys) x times`. for example, if keys is ["img", "seg"]
                and times is 2, names can be: ["img_1", "seg_1", "img_2", "seg_2"].
                if None, use "{key}_{index}" as key for copy times `N`, index from `0` to `N-1`.
            allow_missing_keys: don't raise exception if key is missing.

        Raises:
            ValueError: When ``times`` is nonpositive.
            ValueError: When ``len(names)`` is not ``len(keys) * times``. Incompatible values.

        r!  ztimes must be positive, got r   Nc                   s*   g | ]"}t  jD ]}| d | qqS )r   )r   r@  )r   r   r   r   r   r   r     s       z'CopyItemsd.__init__.<locals>.<listcomp>z8len(names) must match len(keys) * times, got len(names)=z len(keys) * times=)r   r   r   r@  r   r6   r   rA  )r   r   r@  rA  r   r   rB  r   r   j  s    $zCopyItemsd.__init__r   r   r   c                 C  s   t |}t| j}t| jD ]x}| || j|| |d |  D ]P\}}||krbtd| d|| }t|t	j
tjfrt|nt|||< qBq|S )zi
        Raises:
            KeyError: When a key in ``self.names`` already exists in ``data``.

        r!  zKey z already exists in data.)r   r   r   r   r@  r   rA  KeyErrorr   torchTensorr   ndarrayr   
copy_itemsr   )r   r   r   Zkey_lenr   r   new_keyvalr   r   r   r     s    
*,zCopyItemsd.__call__)r!  NFr+  r   r   r   r   rP   b  s      $c                      sL   e Zd ZdZejejgZddddddd	 fd
dZdddddZ	  Z
S )rJ   a  
    Concatenate specified items from data dictionary together on the first dim to construct a big array.
    Expect all the items are numpy array or PyTorch Tensor or MetaTensor.
    Return the first input's meta information when items are MetaTensor.
    r   Fr   r
  r   r   r   )r   r;  r   r   r   c                   s   t  || || _|| _dS )a  
        Args:
            keys: keys of the corresponding items to be concatenated together.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            name: the name corresponding to the key to store the concatenated data.
            dim: on which dimension to concatenate the items, default is 0.
            allow_missing_keys: don't raise exception if key is missing.
        N)r   r   r;  r   )r   r   r;  r   r   r   r   r   r     s    	zConcatItemsd.__init__r   r   r   c                 C  s   t |}g }d}| |D ]>}|dkr4t|| }nt|| |sJtd|||  qt|dkrj|S |tjkrtj	|| j
d|| j< n4t|tjrtj|| j
d|| j< ntd| d|S )z
        Raises:
            TypeError: When items in ``data`` differ in type.
            TypeError: When the item type is not in ``Union[numpy.ndarray, torch.Tensor, MetaTensor]``.

        Nz*All items in data must have the same type.r   axis)r   zUnsupported data type: zB, available options are (numpy.ndarray, torch.Tensor, MetaTensor).)r   r   typer   	TypeErrorr   r   r   rF  r5   r   r;  
issubclassrD  rE  cat)r   r   r   r   r  r   r   r   r   r     s&    

zConcatItemsd.__call__)r   Fr+  r   r   r   r   rJ     s   c                	      sZ   e Zd ZdZejZedddfdddddddd	 fd
dZdddddZdd Z	  Z
S )ro   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.Lambda`.

    For example:

    .. code-block:: python
        :emphasize-lines: 2

        input_data={'image': np.zeros((10, 2, 2)), 'label': np.ones((10, 2, 2))}
        lambd = Lambdad(keys='label', func=lambda x: x[:4, :, :])
        print(lambd(input_data)['label'].shape)
        (4, 2, 2)


    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        func: Lambda/function to be applied. It also can be a sequence of Callable,
            each element corresponds to a key in ``keys``.
        inv_func: Lambda/function of inverse operation if want to invert transforms, default to `lambda x: x`.
            It also can be a sequence of Callable, each element corresponds to a key in ``keys``.
        track_meta:  If `False`, then standard data objects will be returned (e.g., torch.Tensor` and `np.ndarray`)
            as opposed to MONAI's enhanced objects. By default, this is `True`.
        overwrite: whether to overwrite the original data in the input dictionary with lambda function output. it
            can be bool or str, when setting to str, it will create a new key for the output and keep the value of
            key intact. default to True. it also can be a sequence of bool or str, each element corresponds to a key
            in ``keys``.
        allow_missing_keys: don't raise exception if key is missing.

    Note: The inverse operation doesn't allow to define `extra_info` or access other information, such as the
        image's original size. If need these complicated information, please write a new InvertibleTransform directly.

    TFr   Sequence[Callable] | Callabler   z+Sequence[bool] | bool | Sequence[str] | strr   )r   funcinv_funcr  	overwriter   r   c                   sT   t  || t|t| j| _t|t| j| _t|t| j| _t|d| _	d S )N)r  )
r   r   r7   r   r   rQ  rR  rS  r%   _lambdr   r   rQ  rR  r  rS  r   r   r   r   r     s
    	zLambdad.__init__r   r   r   c                 C  sf   t |}| || j| jD ]F\}}}| j|| |d}|rNt|trN|||< qt|tr|||< q|S )N)imgrQ  )r   r   rQ  rS  rT  r   r   r
  r   r   r   r   rQ  rS  retr   r   r   r     s    


zLambdad.__call__c                 C  sB   t |}| || jD ]&\}}| jj|| d}|r|||< q|S )Nr.  )r   r   rS  rT  r  )r   r   r   r   rS  rX  r   r   r   r    s    
zLambdad.inverse)r   r   r   r   r%   r   r   r   r   r  r   r   r   r   r   ro     s   " 
c                
   @  sV   e Zd ZdZejZeddddfdddddd	dd
dddZdd ZdddddZ	dS )r|   a  
    Randomizable version :py:class:`monai.transforms.Lambdad`, the input `func` may contain random logic,
    or randomly execute the function based on `prob`. so `CacheDataset` will not execute it and cache the results.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        func: Lambda/function to be applied. It also can be a sequence of Callable,
            each element corresponds to a key in ``keys``.
        inv_func: Lambda/function of inverse operation if want to invert transforms, default to `lambda x: x`.
            It also can be a sequence of Callable, each element corresponds to a key in ``keys``.
        track_meta:  If `False`, then standard data objects will be returned (e.g., torch.Tensor` and `np.ndarray`)
            as opposed to MONAI's enhanced objects. By default, this is `True`.
        overwrite: whether to overwrite the original data in the input dictionary with lambda function output.
            default to True. it also can be a sequence of bool, each element corresponds to a key in ``keys``.
        prob: probability of executing the random function, default to 1.0, with 100% probability to execute.
            note that all the data specified by `keys` will share the same random probability to execute or not.
        allow_missing_keys: don't raise exception if key is missing.

    For more details, please check :py:class:`monai.transforms.Lambdad`.

    Note: The inverse operation doesn't allow to define `extra_info` or access other information, such as the
        image's original size. If need these complicated information, please write a new InvertibleTransform directly.
    T      ?Fr   rP  r   r  floatr   )r   rQ  rR  r  rS  probr   r   c              	   C  s,   t j| ||||||d tj| |dd d S )NrU  T)r   r[  do_transform)ro   r   r   )r   r   rQ  rR  r  rS  r[  r   r   r   r   r   7  s    
	zRandLambdad.__init__c                 C  s   |  | t|}| || j| jD ]j\}}}|| }t|tsHt|}| jrx| j||d}| j	|d| j
|id n
| 	| |r$|||< q$|S )N)rQ  lambda_infor  )	randomizer   r   rQ  rS  r   r   _do_transformrT  r  r  rW  r   r   r   r   L  s    



zRandLambdad.__call__r   r   r   c                 C  s   t |}| || jD ]d\}}t|| tr| || }|tj r|| j	|tj
 d  | j|| }|r|||< q|S )Nr]  )r   r   rS  r   r   r  r9   DO_TRANSFORMapplied_operationsr   r  rT  r  )r   r   r   r   rS  trrX  r   r   r   r  \  s    

zRandLambdad.inverseN)
r   r   r   r   r%   r   r   r   r   r  r   r   r   r   r|     s   c                      sF   e Zd ZdZejZddddddd fdd	Zd
ddddZ  ZS )rl   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.LabelToMask`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        select_labels: labels to generate mask from. for 1 channel label, the `select_labels`
            is the expected label values, like: [1, 2, 3]. for One-Hot format label, the
            `select_labels` is the expected channel indices.
        merge_channels: whether to use `np.any()` to merge the result on channel dim.
            if yes, will return a single channel mask with binary data.
        allow_missing_keys: don't raise exception if key is missing.

    Fr   zSequence[int] | intr   r   )r   select_labelsmerge_channelsr   r   c                   s    t  || t||d| _d S )N)rc  rd  )r   r   r$   r   )r   r   rc  rd  r   r   r   r   r   {  s    zLabelToMaskd.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r   r   r   r     s    zLabelToMaskd.__call__)FF)	r   r   r   r   r$   r   r   r   r   r   r   r   r   rl   i  s     
c                
      sL   e Zd ZdZejZddddd	d
dddd fddZdddddZ  ZS )rb   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.FgBgToIndices`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        fg_postfix: postfix to save the computed foreground indices in dict.
            for example, if computed on `label` and `postfix = "_fg_indices"`, the key will be `label_fg_indices`.
        bg_postfix: postfix to save the computed background indices in dict.
            for example, if computed on `label` and `postfix = "_bg_indices"`, the key will be `label_bg_indices`.
        image_key: if image_key is not None, use ``label == 0 & image > image_threshold`` to determine
            the negative sample(background). so the output items will not map to all the voxels in the label.
        image_threshold: if enabled image_key, use ``image > image_threshold`` to determine
            the valid image content area and select background only in this area.
        output_shape: expected shape of output indices. if not None, unravel indices to specified shape.
        allow_missing_keys: don't raise exception if key is missing.

    _fg_indices_bg_indicesNr=  Fr   r
  r0  rZ  r  r   r   )r   
fg_postfix
bg_postfix	image_keyimage_thresholdoutput_shaper   r   c                   s0   t  || || _|| _|| _t||| _d S r   )r   r   rg  rh  ri  r    r   )r   r   rg  rh  ri  rj  rk  r   r   r   r   r     s
    
zFgBgToIndicesd.__init__r   r   r   c                 C  s`   t |}| jr|| j nd }| |D ]4}| || |\|t|| j < |t|| j < q&|S r   )r   ri  r   r   r
  rg  rh  r   r   r   imager   r   r   r   r     s
    2zFgBgToIndicesd.__call__)re  rf  Nr=  NF)	r   r   r   r   r    r   r   r   r   r   r   r   r   rb     s         "c                      sL   e Zd ZdZejZddddd	d
ddddd	 fddZddddZ  ZS )r   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.ClassesToIndices`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        indices_postfix: postfix to save the computed indices of all classes in dict.
            for example, if computed on `label` and `postfix = "_cls_indices"`, the key will be `label_cls_indices`.
        num_classes: number of classes for argmax label, not necessary for One-Hot label.
        image_key: if image_key is not None, use ``image > image_threshold`` to define valid region, and only select
            the indices within the valid region.
        image_threshold: if enabled image_key, use ``image > image_threshold`` to determine the valid image content
            area and select only the indices of classes in this area.
        output_shape: expected shape of output indices. if not None, unravel indices to specified shape.
        max_samples_per_class: maximum length of indices to sample in each class to reduce memory consumption.
            Default is None, no subsampling.
        allow_missing_keys: don't raise exception if key is missing.

    _cls_indicesNr=  Fr   r
  
int | Noner0  rZ  r  r   r   )	r   indices_postfixnum_classesri  rj  rk  max_samples_per_classr   r   c	           	        s.   t  || || _|| _t||||| _d S r   )r   r   rp  ri  r   r   )	r   r   rp  rq  ri  rj  rk  rr  r   r   r   r   r     s    zClassesToIndicesd.__init__r  r.  c                 C  sN   t |}| jr|| j nd }| |D ]"}| || ||t|| j < q&|S r   )r   ri  r   r   r
  rp  rl  r   r   r   r     s
     zClassesToIndicesd.__call__)rn  NNr=  NNF)	r   r   r   r   r   r   r   r   r   r   r   r   r   r     s          $c                      s@   e Zd ZdZejZdddd fddZdd	d
ddZ  ZS )rM   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.ConvertToMultiChannelBasedOnBratsClasses`.
    Convert labels to multi channels based on brats18 classes:
    label 1 is the necrotic and non-enhancing tumor core
    label 2 is the peritumoral edema
    label 4 is the GD-enhancing tumor
    The possible classes are TC (Tumor core), WT (Whole tumor)
    and ET (Enhancing tumor).
    Fr   r   r   r   c                   s   t  || t | _d S r   )r   r   r   r   r   r   r   r   r     s    z2ConvertToMultiChannelBasedOnBratsClassesd.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r   r   r   r     s    z2ConvertToMultiChannelBasedOnBratsClassesd.__call__)F)	r   r   r   r   r   r   r   r   r   r   r   r   r   rM     s   
c                
   @  sT   e Zd ZdZejZddd	d
ddddddddZdddddZdddddZdS )rA   a^  
    Dictionary-based wrapper of :py:class:`monai.transforms.AddExtremePointsChannel`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        label_key: key to label source to get the extreme points.
        background: Class index of background label, defaults to 0.
        pert: Random perturbation amount to add to the points, defaults to 0.0.
        sigma: if a list of values, must match the count of spatial dimensions of input data,
            and apply every value in the list to 1 spatial dimension. if only 1 value provided,
            use it for all spatial dimensions.
        rescale_min: minimum value of output data.
        rescale_max: maximum value of output data.
        allow_missing_keys: don't raise exception if key is missing.

    r   r=        @      rY  Fr   r
  r   rZ  z?Sequence[float] | float | Sequence[torch.Tensor] | torch.Tensorr   )r   	label_key
backgroundpertsigmarescale_minrescale_maxr   c	           	      C  s<   t | || || _|| _g | _|| _|| _|| _|| _d S r   )	r   r   rw  rx  pointsrv  ry  rz  r{  )	r   r   rv  rw  rx  ry  rz  r{  r   r   r   r   r     s    z!AddExtremePointsChanneld.__init__r   r   )labelr   c                 C  s   t || j| j| jd| _d S )N)
rand_staterw  rx  )r4   Rrw  rx  r|  )r   r}  r   r   r   r^  -  s    z"AddExtremePointsChanneld.randomizer   r   r   c                 C  s   t |}|| j }|jd dkr(td| |dd d f  | |D ]H}|| }t| j|| j| j	| j
d}t||^}}t||gdd||< qH|S )Nr   r!  z$Only supports single channel labels!)r|  r}  ry  rz  r{  rJ  )r   rv  shaper   r^  r   r3   r|  ry  rz  r{  r;   r5   )r   r   r   r}  r   rV  points_imager   r   r   r   r   0  s"    
z!AddExtremePointsChanneld.__call__N)r   r=  rt  ru  rY  F)	r   r   r   r   r   r   r   r^  r   r   r   r   r   rA     s         c                      sD   e Zd ZdZejZdddddd fdd	Zd
ddddZ  ZS )r   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.TorchVision` for non-randomized transforms.
    For randomized transforms of TorchVision use :py:class:`monai.transforms.RandTorchVisiond`.

    Note:
        As most of the TorchVision transforms only work for PIL image and PyTorch Tensor, this transform expects input
        data to be dict of PyTorch Tensors, users can easily call `ToTensord` transform to convert Numpy to Tensor.
    Fr   r
  r   r   r   r;  r   r   c                   s*   t  || || _t|f||| _dS )a  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            name: The transform name in TorchVision package.
            allow_missing_keys: don't raise exception if key is missing.
            args: parameters for the TorchVision transform.
            kwargs: parameters for the TorchVision transform.

        N)r   r   r;  r0   transr   r   r;  r   argskwargsr   r   r   r   S  s    zTorchVisiond.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r  r   r   r   r   r   b  s    zTorchVisiond.__call__)F)	r   r   r   r   r0   r   r   r   r   r   r   r   r   r   G  s   	c                   @  s<   e Zd ZdZejZdddddddd	Zd
ddddZdS )r   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.TorchVision` for randomized transforms.
    For deterministic non-randomized transforms of TorchVision use :py:class:`monai.transforms.TorchVisiond`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        name: The transform name in TorchVision package.
        allow_missing_keys: don't raise exception if key is missing.
        args: parameters for the TorchVision transform.
        kwargs: parameters for the TorchVision transform.

    Note:

        - As most of the TorchVision transforms only work for PIL image and PyTorch Tensor, this transform expects input
          data to be dict of PyTorch Tensors. Users should call `ToTensord` transform first to convert Numpy to Tensor.
        - This class inherits the ``Randomizable`` purely to prevent any dataset caching to skip the transform
          computation. If the random factor of the underlying torchvision transform is not derived from `self.R`,
          the results may not be deterministic. See Also: :py:class:`monai.transforms.Randomizable`.

    Fr   r
  r   r   r  c                 O  s*   t | || || _t|f||| _d S r   )r   r   r;  r0   r  r  r   r   r   r     s    zRandTorchVisiond.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r  r   r   r   r   r     s    zRandTorchVisiond.__call__N)F)r   r   r   r   r0   r   r   r   r   r   r   r   r   i  s   c                      sN   e Zd ZdZejZejdfddddddd fd	d
ZdddddZ	  Z
S )rr   zQ
    Dictionary-based wrapper of :py:class:`monai.transforms.MapLabelValue`.
    Fr   r   r
   r   r   )r   orig_labelstarget_labelsr   r   r   c                   s"   t  || t|||d| _dS )a8  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            orig_labels: original labels that map to others.
            target_labels: expected label values, 1: 1 map to the `orig_labels`.
            dtype: convert the output data to dtype, default to float32.
                if dtype is from PyTorch, the transform will use the pytorch backend, else with numpy backend.
            allow_missing_keys: don't raise exception if key is missing.

        )r  r  r   N)r   r   r&   mapper)r   r   r  r  r   r   r   r   r   r     s    zMapLabelValued.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   )r   r   r  r   r   r   r   r     s    zMapLabelValued.__call__)r   r   r   r   r&   r   r   r   r   r   r   r   r   r   r   rr     s   c                      sV   e Zd ZdZejZdddedfddddddddd	d
	 fddZddddZ  Z	S )rf   aK	  
    Dictionary-based wrapper of :py:class:`monai.transforms.IntensityStats`.
    Compute statistics for the intensity values of input image and store into the metadata dictionary.
    For example: if `ops=[lambda x: np.mean(x), "max"]` and `key_prefix="orig"`, may generate below stats:
    `{"orig_custom_0": 1.5, "orig_max": 3.0}`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        ops: expected operations to compute statistics for the intensity.
            if a string, will map to the predefined operations, supported: ["mean", "median", "max", "min", "std"]
            mapping to `np.nanmean`, `np.nanmedian`, `np.nanmax`, `np.nanmin`, `np.nanstd`.
            if a callable function, will execute the function on input image.
        key_prefix: the prefix to combine with `ops` name to generate the key to store the results in the
            metadata dictionary. if some `ops` are callable functions, will use "{key_prefix}_custom_{index}"
            as the key, where index counts from 0.
        mask_keys: if not None, specify the mask array for the image to extract only the interested area to compute
            statistics, mask must have the same shape as the image.
            it should be a sequence of strings or None, map to the `keys`.
        channel_wise: whether to compute statistics for every channel of input image separately.
            if True, return a list of values for every operation, default to False.
        meta_keys: explicitly indicate the key of the corresponding metadata dictionary.
            used to store the computed statistics to the meta dict.
            for example, for data with key `image`, the metadata by default is in `image_meta_dict`.
            the metadata is a dictionary object which contains: filename, original_shape, etc.
            it can be a sequence of string, map to the `keys`.
            if None, will try to construct meta_keys by `key_{meta_key_postfix}`.
        meta_key_postfix: if meta_keys is None, use `key_{postfix}` to fetch the metadata according
            to the key data, default is `meta_dict`, the metadata is a dictionary object.
            used to store the computed statistics to the meta dict.
        allow_missing_keys: don't raise exception if key is missing.

    NFr   zSequence[str | Callable]r
  r/  r   r   )	r   ops
key_prefix	mask_keyschannel_wise	meta_keysmeta_key_postfixr   r   c	           	        s   t  || t|||d| _|d kr6td t| jnt|| _|d krXtd t| jnt|| _	t| jt| j	kr~t
dt|t| j| _d S )N)r  r  r  z.meta_keys should have the same length as keys.)r   r   r#   statsr7   r   r   r6   r  r  r   r  )	r   r   r  r  r  r  r  r  r   r   r   r   r     s    ""zIntensityStatsd.__init__r   )r   c                 C  sz   t |}| || j| j| jD ]V\}}}}|p:| d| }| j|| |||d k	r`||nd d\||< ||< q|S )Nr   )rV  	meta_datamask)r   r   r  r  r  r  get)r   r   r   r   mask_keymeta_keyr  r   r   r   r     s         zIntensityStatsd.__call__)
r   r   r   r   r#   r   DEFAULT_POST_FIXr   r   r   r   r   r   r   rf     s   "$c                      sD   e Zd ZdZejZdddddd fdd	Zd
ddddZ  ZS )r   zL
    Dictionary-based wrapper of :py:class:`monai.transforms.ToDevice`.
    Fr   ztorch.device | strr   r   )r   r  r   r   c                   s&   t  || tf d|i|| _dS )a  
        Args:
            keys: keys of the corresponding items to be transformed.
                See also: :py:class:`monai.transforms.compose.MapTransform`
            device: target device to move the Tensor, for example: "cuda:1".
            allow_missing_keys: don't raise exception if key is missing.
            kwargs: other args for the PyTorch `Tensor.to()` API, for more details:
                https://pytorch.org/docs/stable/generated/torch.Tensor.to.html.
        r  N)r   r   r-   r   )r   r   r  r   r  r   r   r   r     s    zToDeviced.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   r   r   r   r   r   r     s    zToDeviced.__call__)F)	r   r   r   r   r-   r   r   r   r   r   r   r   r   r     s
    c                      s6   e Zd ZdZdddddd fdd	Zd
d Z  ZS )rQ   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.CuCIM` for non-randomized transforms.
    For randomized transforms of CuCIM use :py:class:`monai.transforms.RandCuCIMd`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        name: The transform name in CuCIM package.
        allow_missing_keys: don't raise exception if key is missing.
        args: parameters for the CuCIM transform.
        kwargs: parameters for the CuCIM transform.

    Note:
        CuCIM transforms only work with CuPy arrays, this transform expects input data to be `cupy.ndarray`.
        Users can call `ToCuPy` transform to convert a numpy array or torch tensor to cupy array.
    Fr   r
  r   r   r  c                   s,   t  j||d || _t|f||| _d S )Nrs  )r   r   r;  r   r  r  r   r   r   r   %  s    zCuCIMd.__init__c                 C  s.   t |}| |D ]}| || ||< q|S z
        Args:
            data: Dict[Hashable, `cupy.ndarray`]

        Returns:
            Dict[Hashable, `cupy.ndarray`]

        r  r   r   r   r   r   *  s    	zCuCIMd.__call__)F)r   r   r   r   r   r   r   r   r   r   r   rQ     s   c                   @  s.   e Zd ZdZdddddddd	Zd
d ZdS )rv   a`  
    Dictionary-based wrapper of :py:class:`monai.transforms.CuCIM` for randomized transforms.
    For deterministic non-randomized transforms of CuCIM use :py:class:`monai.transforms.CuCIMd`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        name: The transform name in CuCIM package.
        allow_missing_keys: don't raise exception if key is missing.
        args: parameters for the CuCIM transform.
        kwargs: parameters for the CuCIM transform.

    Note:
        - CuCIM transform only work with CuPy arrays, so this transform expects input data to be `cupy.ndarray`.
          Users should call `ToCuPy` transform first to convert a numpy array or torch tensor to cupy array.
        - This class inherits the ``Randomizable`` purely to prevent any dataset caching to skip the transform
          computation. If the random factor of the underlying cuCIM transform is not derived from `self.R`,
          the results may not be deterministic. See Also: :py:class:`monai.transforms.Randomizable`.
    Fr   r
  r   r   r  c                 O  s*   t | || || _t|f||| _d S r   )r   r   r;  r   r  r  r   r   r   r   N  s    zRandCuCIMd.__init__c                 C  s.   t |}| |D ]}| || ||< q|S r  r  r   r   r   r   r   S  s    	zRandCuCIMd.__call__N)F)r   r   r   r   r   r   r   r   r   r   rv   9  s   c                      sD   e Zd ZdZejZdddddd fdd	Zd
ddddZ  ZS )r>   am  
    Dictionary-based wrapper of :py:class:`monai.transforms.AddCoordinateChannels`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: :py:class:`monai.transforms.compose.MapTransform`
        spatial_dims: the spatial dimensions that are to have their coordinates encoded in a channel and
            appended to the input image. E.g., `(0, 1, 2)` represents `H, W, D` dims and append three channels
            to the input image, encoding the coordinates of the input's three spatial dimensions.
        allow_missing_keys: don't raise exception if key is missing.

    Fr   zSequence[int]r   r   )r   spatial_dimsr   r   c                   s   t  || t|d| _d S )N)r  )r   r   r   add_coordinate_channels)r   r   r  r   r   r   r   r   r  s    zAddCoordinateChannelsd.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   )r   r   r  r   r   r   r   r   v  s    zAddCoordinateChannelsd.__call__)F)	r   r   r   r   r   r   r   r   r   r   r   r   r   r>   b  s   c                      sF   e Zd ZdZejZddddddd	 fd
dZdddddZ  ZS )ri   a  
    Dictionary-based wrapper of :py:class:`monai.transforms.ImageFilter`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: monai.transforms.MapTransform
        kernel:
            A string specifying the kernel or a custom kernel as `torch.Tenor` or `np.ndarray`.
            Available options are: `mean`, `laplacian`, `elliptical`, `sobel_{w,h,d}``
        kernel_size:
            A single integer value specifying the size of the quadratic or cubic kernel.
            Computational complexity increases exponentially with kernel_size, which
            should be considered when choosing the kernel size.
        allow_missing_keys:
            Don't raise exception if key is missing.
    NFr   str | NdarrayOrTensorro  r   r   )r   kernelkernel_sizer   r   c                   s"   t  || t||f|| _d S r   )r   r   r"   filter)r   r   r  r  r   r  r   r   r   r     s    zImageFilterd.__init__r   r   r   c                 C  s.   t |}| |D ]}| || ||< q|S r   )r   r   r  r   r   r   r   r     s    zImageFilterd.__call__)NF)	r   r   r   r   r"   r   r   r   r   r   r   r   r   ri   }  s     c                   @  s@   e Zd ZdZejZdddddd	d
dddZdddddZdS )ry   a<  
    Dictionary-based wrapper of :py:class:`monai.transforms.RandomFilterKernel`.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: monai.transforms.MapTransform
        kernel:
            A string specifying the kernel or a custom kernel as `torch.Tenor` or `np.ndarray`.
            Available options are: `mean`, `laplacian`, `elliptical`, `sobel_{w,h,d}``
        kernel_size:
            A single integer value specifying the size of the quadratic or cubic kernel.
            Computational complexity increases exponentially with kernel_size, which
            should be considered when choosing the kernel size.
        prob:
            Probability the transform is applied to the data
        allow_missing_keys:
            Don't raise exception if key is missing.
    N皙?Fr   r  ro  rZ  r   r   )r   r  r  r[  r   r   c                 K  s.   t | || t| | t||f|| _d S r   )r   r   r   r"   r  )r   r   r  r  r[  r   r  r   r   r   r     s    	zRandImageFilterd.__init__r   r   r   c                 C  s>   t |}| d  | jr:| |D ]}| || ||< q"|S r   )r   r^  r_  r   r  r   r   r   r   r     s    
zRandImageFilterd.__call__)Nr  F)r   r   r   r   r"   r   r   r   r   r   r   r   ry     s      )r   
__future__r   r"  collections.abcr   r   r   copyr   typingr   r   r	   numpyr   rD  monai.configr
   r   monai.config.type_definitionsr   monai.data.meta_tensorr   r   monai.data.utilsr   monai.transforms.inverser   monai.transforms.traitsr   r   monai.transforms.transformr   r   r   monai.transforms.utility.arrayr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   monai.transforms.utilsr3   r4   0monai.transforms.utils_pytorch_numpy_unificationr5   monai.utilsr6   r7   monai.utils.enumsr8   r9   r:   monai.utils.type_conversionr;   __all__r   r  re   rD   r\   r   r   r   rG   r   r_   r   r   r   r   rY   r   rs   r   rV   r   rP   rJ   ro   r|   rl   rb   r   rM   rA   r   r   rr   rf   r   rQ   rv   r>   ri   ry   RandImageFilterDRandImageFilterDictImageFilterDImageFilterDictrc   rd   rB   rC   rZ   r[   r   r   r   r   r   r   rE   rF   r   r   r]   r^   r   r   r   r   r   r   r   r   rW   rX   r   r   r   r   rT   rU   r   r   rN   rO   rH   rI   rm   rn   rj   rk   r`   ra   r   r   rK   rL   r?   r@   r   r   r}   r~   rz   r{   rp   rq   rg   rh   r   r   rR   rS   rw   rx   r<   r=   rt   ru   r   r   r   r   <module>   s  |q B#34!"#&1;=5GN$/0C"%$D&)&,