o
    i:                    @  s  d Z ddlmZ ddlZddlmZmZmZmZ ddl	m
Z
 ddl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@mAZAmBZBmCZC ddlDmEZEmFZF ddlGmHZH ddlImJZJmKZK ddlLmMZMmNZNmOZO ddlPmQZQ g dZReMS ZTG dd de!ZUG dd de!ZVG dd de!ZWG dd de!ZXG dd de!ZYG dd  d e!eZZG d!d" d"e!Z[G d#d$ d$e!eZ\G d%d& d&e!Z]G d'd( d(e!Z^G d)d* d*e!Z_G d+d, d,e!Z`G d-d. d.e!eZaG d/d0 d0e!ZbG d1d2 d2e!ZcG d3d4 d4e!ZdG d5d6 d6e!ZeG d7d8 d8e!ZfG d9d: d:e!ZgG d;d< d<e!ZhG d=d> d>e!ZiG d?d@ d@e!eZjG dAdB dBeje#ZkG dCdD dDe!ZlG dEdF dFe!eZmG dGdH dHe!eZnG dIdJ dJe!ZoG dKdL dLe"e!ZpG dMdN dNe!ZqG dOdP dPe!eZrG dQdR dRe!ZsG dSdT dTe!eZtG dUdV dVe!ZuG dWdX dXe!ZvG dYdZ dZe!ZwG d[d\ d\e!ZxG d]d^ d^e!eZyG d_d` d`e!ZzG dadb dbe!Z{G dcdd dde!e#Z|G dedf dfe!eZ}e| Z~Ze{ ZZeU ZZeV ZZeW ZZeY ZZeX ZZeZ ZZe[ ZZe\ ZZe] ZZe^ ZZe_ ZZe` ZZea ZZeb ZZec ZZee ZZef ZZeg ZZeh ZZei ZZej ZZel ZZem ZZen ZZeo ZZep ZZes ZZeq ZZer ZZet ZZek ZZeu ZZev ZZew ZZex ZZey ZZez ZZed ZZe} ZZdS )gz
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Sequence)deepcopy)Anycast)	DtypeLikeKeysCollection)NdarrayOrTensor)MetaObj
MetaTensor)no_collation)InvertibleTransform)MultiSampleTraitRandomizableTrait)MapTransformRandomizableRandomizableTransform)AddCoordinateChannelsAddExtremePointsChannelApplyTransformToPointsAsChannelLast
CastToTypeClassesToIndices(ConvertToMultiChannelBasedOnBratsClassesCuCIM	DataStatsEnsureChannelFirst
EnsureTypeFgBgToIndicesIdentityImageFilterIntensityStatsLabelToMaskLambdaMapLabelValueRemoveRepeatedChannelRepeatChannelSimulateDelaySplitDim
SqueezeDimToCupyToDeviceToNumpyToPILTorchIOTorchVisionToTensor	Transpose)extreme_points_to_imageget_extreme_points)concatenate)ensure_tupleensure_tuple_rep)PostFix	TraceKeysTransformBackends)convert_to_dst_type)w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RandTorchIOdRandTorchIODRandTorchIODict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TorchIODTorchIODictTorchIOdTorchVisionDTorchVisionDictTorchVisiond
TransposedTransposeDict
TransposeDClassesToIndicesdClassesToIndicesDClassesToIndicesDictApplyTransformToPointsdApplyTransformToPointsDApplyTransformToPointsDictc                      4   e Zd ZdZejZdd fd	d
ZdddZ  ZS )rg   zL
    Dictionary-based wrapper of :py:class:`monai.transforms.Identity`.
    Fkeysr   allow_missing_keysboolreturnNonec                      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__ e/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/transforms/utility/dictionary.pyr      s   zIdentityd.__init__data"Mapping[Hashable, NdarrayOrTensor]dict[Hashable, NdarrayOrTensor]c                 C  .   t |}| |D ]}| || ||< q	|S N)dictkey_iteratorr   r   r   dkeyr   r   r   __call__      zIdentityd.__call__Fr   r   r   r   r   r   r   r   r   r   )	__name__
__module____qualname____doc__r"   backendr   r   __classcell__r   r   r   r   rg      
    rg   c                      s4   e Zd ZdZejZdd fddZdddZ  ZS )rF   zQ
    Dictionary-based wrapper of :py:class:`monai.transforms.AsChannelLast`.
    r   Fr   r   channel_dimintr   r   r   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  r   r   r   r   r   r   r   r   r   r      r   zAsChannelLastd.__call__r   F)r   r   r   r   r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   r   r   r   r   rF      r   rF   c                      s6   e Zd ZdZejZ	dd fddZdddZ  ZS )r^   zV
    Dictionary-based wrapper of :py:class:`monai.transforms.EnsureChannelFirst`.
    TFNr   r   strict_checkr   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`
            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__r   Mapping[Hashable, torch.Tensor]dict[Hashable, torch.Tensor]c                 C  sL   t |}| |D ]}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   r   r   r   r   r   r   r   r   r   r   r   r^      s    r^   c                      4   e Zd ZdZejZdd fddZdddZ  ZS )r   zQ
    Dictionary-based wrapper of :py:class:`monai.transforms.RepeatChannel`.
    Fr   r   repeatsr   r   r   r   r   c                      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         zRepeatChanneld.__init__r   r   r   c                 C  r   r   r   r   r   r   r   r   r   r   +  r   zRepeatChanneld.__call__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   r   c                      r   )r   zY
    Dictionary-based wrapper of :py:class:`monai.transforms.RemoveRepeatedChannel`.
    Fr   r   r   r   r   r   r   r   c                   r   r   )r   r   r(   r   r   r   r   r   r   9  r   zRemoveRepeatedChanneld.__init__r   r   r   c                 C  r   r   r   r   r   r   r   r   D  r   zRemoveRepeatedChanneld.__call__r   r   r   )	r   r   r   r   r(   r   r   r   r   r   r   r   r   r   2  r   r   c                      s<   e Zd ZejZ						dd fddZdddZ  ZS )r   Nr   TFr   r   output_postfixesSequence[str] | Nonedimr   keepdimr   update_metalist_outputr   r   r   c                   sL   t  || || _t|||| _|| _| jdu r"| jdur$tddS 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   N  s   zSplitDimd.__init__r   r   Adict[Hashable, torch.Tensor] | list[dict[Hashable, torch.Tensor]]c                   s<  t | tt }jrGg } fdd|D }t| D ]$}t t||}t  t|D ]
}t | ||< q4|	| q |S |D ]R}
 | }	jd u r_ttt|	nj}
t|
t|	krytdt|
 dt|	 dt|	D ]\}}| d|
|  }| v rtd| d| |< q}qI S )Nc                   s   g | ]	}  | qS r   )r   .0r   r   r   r   r   
<listcomp>w  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   retsZ	postfixesirZ	split_keyr   r   r   r   o  s.    
zSplitDimd.__call__)Nr   TTFF)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   r   r   r   r   r   r   r   r   K  s    !r   c                   @  s2   e Zd ZdZejZejdfdddZdddZ	dS )rI   zN
    Dictionary-based wrapper of :py:class:`monai.transforms.CastToType`.
    Fr   r   dtype;Sequence[DtypeLike | torch.dtype] | DtypeLike | torch.dtyper   r   r   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   r9   r  r   r  r   r   )r   r   r  r   r   r   r   r     s   zCastToTyped.__init__r   r   r   c                 C  :   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   r   r   r   )
r   r   r   r   r   r   npfloat32r   r   r   r   r   r   rI     s    rI   c                      sH   e Zd ZdZejZ					dd fddZdddZdddZ  Z	S )r   zL
    Dictionary-based wrapper of :py:class:`monai.transforms.ToTensor`.
    NTFr   r   r  torch.dtype | Nonedevicetorch.device | str | Nonewrap_sequencer   
track_metabool | Noner   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 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   r3   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  r  r  r  r   r  r  r   r   r   r   r   )
r   r   r   r   r3   r   r   r   r"  r   r   r   r   r   r     s    
r   c                      s@   e Zd ZdZejZ						dd fddZdddZ  ZS )ra   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   r   	data_typestrr  r  r  torch.device | Noner  r   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   r9   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   r   r   r   )	r   r   r   r   r    r   r   r   r   r   r   r   r   ra     s    ra   c                      :   e Zd ZdZejZ			dd fddZ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                       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__r   Mapping[Hashable, Any]dict[Hashable, Any]c                 C  r   r   r   r   r   r   r   r   1  r   zToNumpyd.__call__NTF)
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   r   r   r     s    r   c                      r'  )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   r   r  np.dtype | Noner  r   r   r   r   c                       t  || t||d| _d S )Nr*  )r   r   r-   r   r+  r   r   r   r   I     zToCupyd.__init__r   r   r   c                 C  r   r   r   r   r   r   r   r   S  r   zToCupyd.__call__r.  )
r   r   r  r0  r  r   r   r   r   r   r   )	r   r   r   r   r-   r   r   r   r   r   r   r   r   r   8  s    
r   c                      r   )r   r(  Fr   r   r   r   r   r   c                   r   )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   r0   r   r   r   r   r   r   a  s   zToPILd.__init__r   r,  r-  c                 C  r   r   r   r   r   r   r   r   k  r   zToPILd.__call__r   r   r/  )	r   r   r   r   r0   r   r   r   r   r   r   r   r   r   Z  s
    
r   c                      s>   e Zd ZdZejZdd fddZdddZdddZ  Z	S )r   zM
    Dictionary-based wrapper of :py:class:`monai.transforms.Transpose`.
    Fr   r   indicesSequence[int] | Noner   r   r   r   c                   s   t  || t|| _d S r   )r   r   r4   	transform)r   r   r3  r   r   r   r   r   y  s   zTransposed.__init__r   r   r   c                 C  sb   t |}| |D ]%}| || ||< | jjp#t|| jd d d }| j||d|id q	|S )Nr3  
extra_info)r   r   r5  r3  r  ndimr  )r   r   r   r   r3  r   r   r   r   }  s    zTransposed.__call__r,  r-  c                 C  sn   t |}| |D ]+}| ||}t|tj d }t|}t|	 }||| ||< | 
|| q	|S )Nr3  )r   r   get_most_recent_transformr  arrayr;   
EXTRA_INFOargsortr4   tolistr   )r   r   r   r   r5  Zfwd_indicesZinv_indicesr!  r   r   r   r"    s   
zTransposed.inverser   )r   r   r3  r4  r   r   r   r   r   r/  )
r   r   r   r   r4   r   r   r   r"  r   r   r   r   r   r   r  s    
	r   c                      s8   e Zd ZdZejejgZdd fddZdd Z	  Z
S )r[   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   sepr%  use_reSequence[bool] | boolr   r   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?  r9   r  r   r@  )r   r   r?  r@  r   r   r   r     s   
zDeleteItemsd.__init__c                   sR   dd fdd t |}tttt | j| jD ]\}} || j||}q|S )NFr@  r   c                   sL   | d  t | dkr| 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   4 z?DeleteItemsd.__call__.<locals>._delete_item.<locals>.<dictcomp>)r  items)r   r   r@  _delete_itemrF  r   rJ    s
   z+DeleteItemsd.__call__.<locals>._delete_itemr   )r@  r   )	r   r  r	   r   r%  r   r@  splitr?  )r   r   r   r   r@  r   rI  r   r     s
    zDeleteItemsd.__call__)r   F)r   r   r?  r%  r@  rA  r   r   r   r   r   r   r<   TORCHNUMPYr   r   r   r   r   r   r   r   r[     s
    r[   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   rG    s    z)SelectItemsd.__call__.<locals>.<dictcomp>)r   r   r   r   rO  r   r     s   zSelectItemsd.__call__N)	r   r   r   r   r<   rM  rN  r   r   r   r   r   r   r     s    r   c                      s>   e Zd ZdZejejgZ			dd fddZdd Z	  Z
S )ru   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   r   sub_keysKeysCollection | Nonedelete_keysr   prefix
str | Noner   r   c                   s"   t  | || _|| _|| _d S r   )r   r   rQ  rS  rT  )r   r   rQ  rS  rT  r   r   r   r     s   
zFlattenSubKeysd.__init__c                 C  s   t |}| |D ]<}| jd u r||  n| j}|D ]#}| jr(| j d| n|}||v r6td| d|| | ||< q| jrE||= q	|S )Nr   'zR' already exists in the top-level keys. Please change `prefix` to avoid duplicity.)r   r   rQ  r   rT  r   rS  )r   r   r   r   rQ  skZsk_topr   r   r   r     s   
zFlattenSubKeysd.__call__)NTN)
r   r   rQ  rR  rS  r   rT  rU  r   r   rL  r   r   r   r   ru     s    ru   c                      s6   e Zd ZdZejZ	dd fddZ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                   r)  )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  r   r   r   r   r   r   r   r     r   zSqueezeDimd.__call__)r   TF)
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     s    r   c                      sF   e Zd ZdZejZ									d d! fddZd"ddZ  ZS )#rX   zM
    Dictionary-based wrapper of :py:class:`monai.transforms.DataStats`.
    DataTFNr   r   r   rT  Sequence[str] | strr$  rA  
data_shapevalue_range
data_value	meta_infoadditional_info$Sequence[Callable] | Callable | Nonenamer%  r   r   r   r   c                   s   t  ||
 t|t| j| _t|t| j| _t|t| j| _t|t| j| _t|t| j| _	t|t| j| _
t|t| j| _t|	d| _dS )ah  
        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.
            meta_info: whether to show the data of MetaTensor.
                it also can be a sequence of bool, each element corresponds to a key in ``keys``.
            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   r9   r  r   rT  r$  rZ  r[  r\  r]  r^  r   printer)r   r   rT  r$  rZ  r[  r\  r]  r^  r`  r   r   r   r   r     s   %zDataStatsd.__init__r   r   r   c                 C  sh   t |}| || j| j| j| j| j| j| jD ]\}}}}}}}	}
| 	|| ||||||	|
||< q|S r   )
r   r   rT  r$  rZ  r[  r\  r]  r^  ra  )r   r   r   r   rT  r$  rZ  r[  r\  r]  r^  r   r   r   r   J  s0   

zDataStatsd.__call__)	rX  TTTFFNr   F)r   r   rT  rY  r$  rA  rZ  rA  r[  rA  r\  rA  r]  rA  r^  r_  r`  r%  r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   r   r   r   r   rX     s    /rX   c                      s6   e Zd ZdZejZ	dd fddZdddZ  ZS )r   zQ
    Dictionary-based wrapper of :py:class:`monai.transforms.SimulateDelay`.
            Fr   r   
delay_timeSequence[float] | floatr   r   r   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   r9   r  r   rc  r*   delayer)r   r   rc  r   r   r   r   r   l  s   zSimulateDelayd.__init__r   r   r   c                 C  r  )N)rc  )r   r   rc  re  )r   r   r   r   rc  r   r   r   r   |  s   zSimulateDelayd.__call__)rb  F)r   r   rc  rd  r   r   r   r   r   )	r   r   r   r   r*   r   r   r   r   r   r   r   r   r   e  s    r   c                      s@   e Zd ZdZejejgZ			dd fddZdddZ	  Z
S )rR   z
    Copy specified items from data dictionary and save with different key names.
    It can copy several items together and copy several times.
    rB  NFr   r   timesr   namesrR  r   r   r   r   c                   s   t  || |dk rtd| d| _|du r$ fdd jD nt|}t|t j| krEt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.

        rB  ztimes must be positive, got r   Nc                   s*   g | ]}t  jD ]	}| d | q	qS )r   )r  rf  )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   rf  r   r8   r  rg  )r   r   rf  rg  r   r   rh  r   r     s   $
zCopyItemsd.__init__r   r   r   c                 C  s   t |}t| j}t| jD ]<}| || j|| |d |  D ](\}}||v r1td| d|| }t|t	j
tjfrCt|nt|||< q!q|S )zi
        Raises:
            KeyError: When a key in ``self.names`` already exists in ``data``.

        rB  zKey z already exists in data.)r   r  r   r  rf  r   rg  KeyErrorr   torchTensorr  ndarrayr   
copy_itemsr   )r   r   r   Zkey_lenr  r   new_keyvalr   r   r   r     s   
**zCopyItemsd.__call__)rB  NF)
r   r   rf  r   rg  rR  r   r   r   r   r   rL  r   r   r   r   rR     s    $rR   c                      s:   e Zd ZdZejejgZdd fddZdddZ	  Z
S )rL   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u rt|| }nt|| |s%td|||  qt|dkr5|S |tju rGtj	|| j
d|| j< |S t|tjrZtj|| j
d|| j< |S td| d)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  rl  r7   r   r`  
issubclassrj  rk  cat)r   r   r   r
  r$  r   r   r   r   r     s(   

zConcatItemsd.__call__r   )
r   r   r`  r%  r   r   r   r   r   r   r   rL  r   r   r   r   rL     s
    rL   c                      sD   e Zd ZdZejZedddfd fddZdddZdd Z	  Z
S )rq   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   r   funcSequence[Callable] | Callableinv_funcr  r   	overwrite+Sequence[bool] | bool | Sequence[str] | strr   r   r   c                   sT   t  || t|t| j| _t|t| j| _t|t| j| _t|d| _	d S )N)r  )
r   r   r9   r  r   rv  rx  ry  r&   _lambdr   r   rv  rx  r  ry  r   r   r   r   r     s
   	zLambdad.__init__r   r   r   c                 C  sf   t |}| || j| jD ]#\}}}| j|| |d}|r't|tr'|||< qt|tr0|||< q|S )N)imgrv  )r   r   rv  ry  r{  r   r   r%  r   r   r   r   rv  ry  retr   r   r   r   )  s   

zLambdad.__call__c                 C  sB   t |}| || jD ]\}}| jj|| d}|r|||< q|S )NrO  )r   r   ry  r{  r"  )r   r   r   r   ry  r  r   r   r   r"  3  s   zLambdad.inverse)r   r   rv  rw  rx  rw  r  r   ry  rz  r   r   r   r   r   )r   r   r   r   r&   r   r   r   r   r"  r   r   r   r   r   rq     s    "

rq   c                   @  s>   e Zd ZdZejZeddddfdddZdd Z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   r   rv  rw  rx  r  r   ry  rA  probfloatr   r   r   c              	   C  s,   t j| ||||||d tj| |dd d S )Nr|  T)r   r  do_transform)rq   r   r   )r   r   rv  rx  r  ry  r  r   r   r   r   r   X  s   
	zRandLambdad.__init__c                 C  s   |  | t|}| || j| jD ]5\}}}|| }t|ts$t|}| jr<| j||d}| j	|d| j
|id n| 	| |rG|||< q|S )N)rv  lambda_infor7  )	randomizer   r   rv  ry  r   r   _do_transformr{  r  r   r~  r   r   r   r   m  s   


zRandLambdad.__call__r   r   r   c                 C  s   t |}| || jD ]2\}}t|| tr=| || }|tj r=|| j	|tj
 d  | j|| }|r=|||< q|S )Nr  )r   r   ry  r   r   r   r;   DO_TRANSFORMapplied_operationsr  r<  r{  r"  )r   r   r   r   ry  trr  r   r   r   r"  }  s   
zRandLambdad.inverseN)r   r   rv  rw  rx  rw  r  r   ry  rA  r  r  r   r   r   r   r   )
r   r   r   r   r&   r   r   r   r   r"  r   r   r   r   r~   <  s    r~   c                      s8   e Zd ZdZejZ		dd fddZdddZ  ZS )rn   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   r   select_labelsSequence[int] | intmerge_channelsr   r   r   r   c                   r1  )N)r  r  )r   r   r%   r   )r   r   r  r  r   r   r   r   r     r2  zLabelToMaskd.__init__r   r   r   c                 C  r   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   r   r   r%   r   r   r   r   r   r   r   r   rn     s    
rn   c                      s@   e Zd ZdZejZ						dd fddZdddZ  ZS ) rd   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_indicesNrb  Fr   r   
fg_postfixr%  
bg_postfix	image_keyrU  image_thresholdr  output_shaper4  r   r   r   r   c                   s0   t  || || _|| _|| _t||| _d S r   )r   r   r  r  r  r!   r   )r   r   r  r  r  r  r  r   r   r   r   r     s
   
zFgBgToIndicesd.__init__r   r   r   c                 C  s`   t |}| jr|| j nd }| |D ]}| || |\|t|| j < |t|| j < q|S r   )r   r  r   r   r%  r  r  r   r   r   imager   r   r   r   r     s
   2zFgBgToIndicesd.__call__)r  r  Nrb  NF)r   r   r  r%  r  r%  r  rU  r  r  r  r4  r   r   r   r   r   )	r   r   r   r   r!   r   r   r   r   r   r   r   r   rd     s    rd   c                      sB   e Zd ZdZejZ							dd fddZ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_indicesNrb  Fr   r   indices_postfixr%  num_classes
int | Noner  rU  r  r  r  r4  max_samples_per_classr   r   r   r   c	           	        s.   t  || || _|| _t||||| _d S r   )r   r   r  r  r   r   )	r   r   r  r  r  r  r  r  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   r  r   r   r%  r  r  r   r   r   r     s
    zClassesToIndicesd.__call__)r  NNrb  NNF)r   r   r  r%  r  r  r  rU  r  r  r  r4  r  r  r   r   r   r   )r   r,  )	r   r   r   r   r   r   r   r   r   r   r   r   r   r     s    r   c                      s4   e Zd ZdZejZdd fddZdddZ  ZS )rO   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   r   c                 C  r   r   r   r   r   r   r   r     r   z2ConvertToMultiChannelBasedOnBratsClassesd.__call__r   )r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   r   r   r   r   rO     s
    
rO   c                   @  sB   e Zd ZdZejZ						d$d%ddZd&ddZd'd!d"Zd#S )(rC   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   rb        @      r  Fr   r   	label_keyr%  
backgroundr   pertr  sigma?Sequence[float] | float | Sequence[torch.Tensor] | torch.Tensorrescale_minrescale_maxr   r   c	           	      C  s<   t | || || _|| _g | _|| _|| _|| _|| _d S r   )	r   r   r  r  pointsr  r  r  r  )	r   r   r  r  r  r  r  r  r   r   r   r   r   :  s   
z!AddExtremePointsChanneld.__init__labelr   r   r   c                 C  s   t || j| j| jd| _d S )N)
rand_stater  r  )r6   Rr  r  r  )r   r  r   r   r   r  N  s   z"AddExtremePointsChanneld.randomizer   r   r   c                 C  s   t |}|| j }|jd dkrtd| |dd d f  | |D ]$}|| }t| j|| j| j	| j
d}t||^}}t||gdd||< q$|S )Nr   rB  z$Only supports single channel labels!)r  r  r  r  r  rp  )r   r  shaper   r  r   r5   r  r  r  r  r=   r7   )r   r   r   r  r   r}  points_imager   r   r   r   r   Q  s"   
z!AddExtremePointsChanneld.__call__N)r   rb  r  r  r  F)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   r   r   r   r  r   r   r   r   r   rC   %  s    
rC   c                      r   )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                   s0   t  || || _t|g|R i || _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`  r2   transr   r   r`  r   argskwargsr   r   r   r   t  s   zTorchVisiond.__init__r   r   r   c                 C  r   r   r   r   r  r   r   r   r   r     r   zTorchVisiond.__call__r   r   r   r`  r%  r   r   r   r   r   )	r   r   r   r   r2   r   r   r   r   r   r   r   r   r   h  s
    	r   c                   @  s,   e Zd ZdZejZddddZ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   r   r   r   c                 O  0   t | || || _t|g|R i || _d S r   )r   r   r`  r2   r  r  r   r   r   r        zRandTorchVisiond.__init__r   r   r   c                 C  r   r   r  r   r   r   r   r     r   zRandTorchVisiond.__call__Nr   r  r   )r   r   r   r   r2   r   r   r   r   r   r   r   r     s
    r   c                      4   e Zd ZdZejZdd fddZdddZ  ZS )r   z
    Dictionary-based wrapper of :py:class:`monai.transforms.TorchIO` for non-randomized transforms.
    For randomized transforms of TorchIO use :py:class:`monai.transforms.RandTorchIOd`.
    Fr   r   r`  r%  r   r   r   r   c                   :   t  || || _| j|d< t|g|R i || _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 TorchIO package.
            allow_missing_keys: don't raise exception if key is missing.
            args: parameters for the TorchIO transform.
            kwargs: parameters for the TorchIO transform.

        includeNr   r   r`  r   r1   r  r  r   r   r   r        
zTorchIOd.__init__r   r   c                 C     t | |S r   r   r  rP  r   r   r   r        zTorchIOd.__call__r   r  r   r   r   r   	r   r   r   r   r1   r   r   r   r   r   r   r   r   r     
    r   c                      r  )r   z
    Dictionary-based wrapper of :py:class:`monai.transforms.TorchIO` for randomized transforms.
    For non-randomized transforms of TorchIO use :py:class:`monai.transforms.TorchIOd`.
    Fr   r   r`  r%  r   r   r   r   c                   r  r  r  r  r   r   r   r     r  zRandTorchIOd.__init__r   r   c                 C  r  r   r  rP  r   r   r   r     r  zRandTorchIOd.__call__r   r  r  r  r   r   r   r   r     r  r   c                      s:   e Zd ZdZejZejdfd fddZdddZ	  Z
S )rt   zQ
    Dictionary-based wrapper of :py:class:`monai.transforms.MapLabelValue`.
    Fr   r   orig_labelsr   target_labelsr  r
   r   r   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  r   r   )r   r   r  r   r   r   r   r     r   zMapLabelValued.__call__)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   r   r   r   rt     s    rt   c                      s>   e Zd ZdZejZdddedfd fddZdddZ  Z	S )rh   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   r   opsSequence[str | Callable]
key_prefixr%  	mask_keysrR  channel_wiser   	meta_keysmeta_key_postfixr   r   r   c	           	        s   t  || t|||d| _|d u rtd t| jnt|| _|d u r,t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$   statsr9   r  r   r8   r  r  r   r  )	r   r   r  r  r  r  r  r  r   r   r   r   r   2  s   ""zIntensityStatsd.__init__r   c                 C  sz   t |}| || j| j| jD ]+\}}}}|p| d| }| j|| |||d ur0||nd d\||< ||< q|S )Nr   )r}  	meta_datamask)r   r   r  r  r  r  get)r   r   r   r   mask_keymeta_keyr  r   r   r   r   E  s   "zIntensityStatsd.__call__)r   r   r  r  r  r%  r  rR  r  r   r  rR  r  r%  r   r   r   r   )r   r   )
r   r   r   r   r$   r   DEFAULT_POST_FIXr   r   r   r   r   r   r   rh     s    "rh   c                      s6   e Zd ZdZejZ	dd fddZdddZ  ZS )r   zL
    Dictionary-based wrapper of :py:class:`monai.transforms.ToDevice`.
    Fr   r   r  torch.device | strr   r   r   r   c                   s&   t  || td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  Nr   )r   r   r.   r   )r   r   r  r   r  r   r   r   r   X  s   zToDeviced.__init__r   r   r   c                 C  r   r   r   r   r   r   r   r   g  r   zToDeviced.__call__r   )r   r   r  r  r   r   r   r   r   )	r   r   r   r   r.   r   r   r   r   r   r   r   r   r   Q  s    r   c                      s,   e Zd ZdZdd fddZdd Z  ZS )rS   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   r   r   r   c                   s2   t  j||d || _t|g|R i || _d S )N)r   r   )r   r   r`  r   r  r  r   r   r   r     s   zCuCIMd.__init__c                 C  r   z
        Args:
            data: Dict[Hashable, `cupy.ndarray`]

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

        r  r   r   r   r   r        	zCuCIMd.__call__r   r  )r   r   r   r   r   r   r   r   r   r   r   rS   n  s    rS   c                   @  s$   e Zd ZdZddddZdd ZdS )rx   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   r   r   r   c                 O  r  r   )r   r   r`  r   r  r  r   r   r   r     r  zRandCuCIMd.__init__c                 C  r   r  r  r   r   r   r   r     r  zRandCuCIMd.__call__Nr   r  )r   r   r   r   r   r   r   r   r   r   rx     s    rx   c                      r   )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   r   spatial_dimsSequence[int]r   r   r   r   c                   s   t  || t|d| _d S )N)r  )r   r   r   add_coordinate_channels)r   r   r  r   r   r   r   r     s   zAddCoordinateChannelsd.__init__r   r   r   c                 C  r   r   )r   r   r  r   r   r   r   r     r   zAddCoordinateChannelsd.__call__r   )r   r   r  r  r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   r   r   r   r   r@     s
    r@   c                      s8   e Zd ZdZejZ		dd fddZdddZ  ZS )rk   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   r   kernelstr | NdarrayOrTensorkernel_sizer  r   r   r   r   c                   s&   t  || t||fi || _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  r   r   )r   r   r  r   r   r   r   r     r   zImageFilterd.__call__)NF)
r   r   r  r  r  r  r   r   r   r   r   )	r   r   r   r   r#   r   r   r   r   r   r   r   r   rk     s    rk   c                   @  s2   e Zd ZdZejZ			ddddZdddZdS )r{   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.

    Note:
        - This transform does not scale output image values automatically to match the range of the input.
          The output should be scaled by later transforms to match the input if this is desired.
    N皙?Fr   r   r  r  r  r  r  r  r   r   r   r   c                 K  s2   t | || t| | t||fi || _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   r   )r   r   r   r   r#   r   r   r   r   r   r   r   r{     s    r{   c                   @  s>   e Zd ZdZdejddddfdddZdddZdddZdS )r   a	  
    Dictionary-based wrapper of :py:class:`monai.transforms.ApplyTransformToPoints`.
    The input coordinates are assumed to be in the shape (C, N, 2 or 3),
    where C represents the number of channels and N denotes the number of points.
    The output has the same shape as the input.

    Args:
        keys: keys of the corresponding items to be transformed.
            See also: monai.transforms.MapTransform
        refer_keys: The key of the reference item used for transformation.
            It can directly refer to an affine or an image from which the affine can be derived. It can also be a
            sequence of keys, in which case each refers to the affine applied to the matching points in `keys`.
        dtype: The desired data type for the output.
        affine: A 3x3 or 4x4 affine transformation matrix applied to points. This matrix typically originates
            from the image. For 2D points, a 3x3 matrix can be provided, avoiding the need to add an unnecessary
            Z dimension. While a 4x4 matrix is required for 3D transformations, it's important to note that when
            applying a 4x4 matrix to 2D points, the additional dimensions are handled accordingly.
            The matrix is always converted to float64 for computation, which can be computationally
            expensive when applied to a large number of points.
            If None, will try to use the affine matrix from the refer data.
        invert_affine: Whether to invert the affine transformation matrix applied to the points. Defaults to ``True``.
            Typically, the affine matrix is derived from the image, while the points are in world coordinates.
            If you want to align the points with the image, set this to ``True``. Otherwise, set it to ``False``.
        affine_lps_to_ras: Defaults to ``False``. Set to `True` if your point data is in the RAS coordinate system
            or you're using `ITKReader` with `affine_lps_to_ras=True`.
            This ensures the correct application of the affine transformation between LPS (left-posterior-superior)
            and RAS (right-anterior-superior) coordinate systems. This argument ensures the points and the affine
            matrix are in the same coordinate system.
        allow_missing_keys: Don't raise exception if key is missing.
    NTFr   r   
refer_keysrR  r  DtypeLike | torch.dtypeaffinetorch.Tensor | Noneinvert_affiner   affine_lps_to_rasr   c                 C  s6   t | || t|t| j| _t||||d| _d S )N)r  r  r  r  )r   r   r9   r  r   r  r   r   )r   r   r  r  r  r  r  r   r   r   r   r   N  s
   
z ApplyTransformToPointsd.__init__r   r   c                 C  sv   t |}| || jD ]-\}}|| }d }|d ur0||v r"|| }ntd| dt|d|}| ||||< q|S )NzThe refer_key 'z' is not found in the data.r  )r   r   r  ri  getattrr   )r   r   r   r   Z	refer_keycoordsr  Z
refer_datar   r   r   r   ^  s   
z ApplyTransformToPointsd.__call__r   r   c                 C  s0   t |}| |D ]}| j|| ||< q	|S r   )r   r   r   r"  r   r   r   r   r"  n  s   zApplyTransformToPointsd.inverse)r   r   r  rR  r  r  r  r  r  r   r  r   r   r   )r   r   r   )	r   r   r   r   rj  float64r   r   r"  r   r   r   r   r   .  s    "
r   )r   
__future__r   rC  collections.abcr   r   r   r   copyr   typingr   r	   numpyr  rj  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   r3   r4   monai.transforms.utilsr5   r6   0monai.transforms.utils_pytorch_numpy_unificationr7   monai.utilsr8   r9   monai.utils.enumsr:   r;   r<   monai.utils.type_conversionr=   __all__r   r  rg   rF   r^   r   r   r   rI   r   ra   r   r   r   r   r[   r   ru   r   rX   r   rR   rL   rq   r~   rn   rd   r   rO   rC   r   r   r   r   rt   rh   r   rS   rx   r@   rk   r{   r   RandImageFilterDRandImageFilterDictImageFilterDImageFilterDictre   rf   rD   rE   r\   r]   r   r   r   r   r   r   rG   rH   r   r   r_   r`   r   r   r   r   r   r   r   r   rY   rZ   r   r   r   r   rV   rW   r   r   rP   rQ   rJ   rK   ro   rp   rl   rm   rb   rc   r   r   rM   rN   rA   rB   r   r   r   r   r   r   r   r   r|   r}   rr   rs   ri   rj   r   r   rT   rU   ry   rz   r>   r?   rv   rw   r   r   r   r   r   r   <module>   s   
!z B#34!"#&1Q=5GN$/0C"%$D&)&0G