o
    i/                     @  s   d dl mZ d dlmZ d dlmZ d dl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 d d
lmZ d dlmZ d dlmZ G dd deZG dd deZG dd deZdS )    )annotations)abstractmethod)SequenceN)Tensor)complex_absconvert_to_tensor_complex)root_sum_of_squares)NdarrayOrTensor)ifftn_centered)RandomizableTransform)TransformBackends)convert_to_tensorc                   @  s8   e Zd ZdZ		ddddZedddZdddZdS )
KspaceMaskaK  
    A basic class for under-sampling mask setup. It provides common
    features for under-sampling mask generators.
    For example, RandomMaskFunc and EquispacedMaskFunc (two mask
    transform objects defined right after this module)
    both inherit MaskFunc to properly setup properties like the
    acceleration factor.
       Tcenter_fractionsSequence[float]accelerationsspatial_dimsint
is_complexboolc                 C  s4   t |t |krtd|| _|| _|| _|| _dS )a  
        Args:
            center_fractions: Fraction of low-frequency columns to be retained.
                If multiple values are provided, then one of these numbers
                is chosen uniformly each time.
            accelerations: Amount of under-sampling. This should have the
                same length as center_fractions. If multiple values are
                provided, then one of these is chosen uniformly each time.
            spatial_dims: Number of spatial dims (e.g., it's 2 for a 2D data;
                it's also 2 for pseudo-3D datasets like the fastMRI dataset).
                The last spatial dim is selected for sampling. For the fastMRI
                dataset, k-space has the form (...,num_slices,num_coils,H,W)
                and sampling is done along W. For a general 3D data with the
                shape (...,num_coils,H,W,D), sampling is done along D.
            is_complex: if True, then the last dimension will be reserved for
                real/imaginary parts.
        zONumber of center fractions                 should match number of accelerationsN)len
ValueErrorr   r   r   r   )selfr   r   r   r    r   l/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/apps/reconstruction/transforms/array.py__init__'   s   
zKspaceMask.__init__kspacer	   returnSequence[Tensor]c                 C  s   t )a  
        This is an extra instance to allow for defining new mask generators.
        For creating other mask transforms, define a new class and simply
        override __call__. See an example of this in
        :py:class:`monai.apps.reconstruction.transforms.array.RandomKspacemask`.

        Args:
            kspace: The input k-space data. The shape is (...,num_coils,H,W,2)
                for complex 2D inputs and (...,num_coils,H,W,D) for real 3D
                data.
        )NotImplementedError)r   r   r   r   r   __call__J   s   zKspaceMask.__call__c                 C  s0   | j dt| j}| j| }| j| }||fS )a  
        If multiple values are provided for center_fractions and
        accelerations, this function selects one value uniformly
        for each training/test sample.

        Returns:
            A tuple containing
                (1) center_fraction: chosen fraction of center kspace
                lines to exclude from under-sampling
                (2) acceleration: chosen acceleration factor
        r   )Rrandintr   r   r   )r   choicecenter_fractionaccelerationr   r   r   randomize_choose_accelerationY   s   

z(KspaceMask.randomize_choose_accelerationN)r   T)r   r   r   r   r   r   r   r   r   r	   r   r   )r   r   )__name__
__module____qualname____doc__r   r   r!   r'   r   r   r   r   r      s    #r   c                   @  "   e Zd ZdZejgZd	ddZdS )
RandomKspaceMaska  
    This k-space mask transform under-samples the k-space according to a
    random sampling pattern. Precisely, it uniformly selects a subset of
    columns from the input k-space data. If the k-space data has N columns,
    the mask picks out:

    1. N_low_freqs = (N * center_fraction) columns in the center
    corresponding to low-frequencies

    2. The other columns are selected uniformly at random with a probability
    equal to:
    prob = (N / acceleration - N_low_freqs) / (N - N_low_freqs).
    This ensures that the expected number of columns selected is equal to
    (N / acceleration)

    It is possible to use multiple center_fractions and accelerations,
    in which case one possible (center_fraction, acceleration) is chosen
    uniformly at random each time the transform is called.

    Example:
        If accelerations = [4, 8] and center_fractions = [0.08, 0.04],
        then there is a 50% probability that 4-fold acceleration with 8%
        center fraction is selected and a 50% probability that 8-fold
        acceleration with 4% center fraction is selected.

    Modified and adopted from:
        https://github.com/facebookresearch/fastMRI/tree/master/fastmri
    r   r	   r   r   c                 C  s  t |}|j}|d }| jr|d }|  \}}tt|| }|| | ||  }| jj|d|k }	|| d d }
d|	|
|
| < dd |D }| jrR||d< n||d< t|	j	| 
tj}	|	| }t|}|	| _ttt|| j| jd	}tt|| j d d
}||fS )a  
        Args:
            kspace: The input k-space data. The shape is (...,num_coils,H,W,2)
                for complex 2D inputs and (...,num_coils,H,W,D) for real 3D
                data. The last spatial dim is selected for sampling. For the
                fastMRI dataset, k-space has the form
                (...,num_slices,num_coils,H,W) and sampling is done along W.
                For a general 3D data with the shape (...,num_coils,H,W,D),
                sampling is done along D.

        Returns:
            A tuple containing
                (1) the under-sampled kspace
                (2) absolute value of the inverse fourier of the under-sampled kspace
        )size   r   Tc                 S     g | ]}d qS r2   r   .0_r   r   r   
<listcomp>       z-RandomKspaceMask.__call__.<locals>.<listcomp>r   r   spatial_dim)r   shaper   r'   r   roundr"   uniformr   reshapeastypenpfloat32maskr   r
   r   r   )r   r   kspace_tspatial_sizenum_colsr%   r&   num_low_freqsprobrD   pad
mask_shapemaskedmasked_kspacemasked_kspace_ifftmasked_kspace_ifft_rssr   r   r   r!      s4   
zRandomKspaceMask.__call__Nr(   r)   r*   r+   r,   r   TORCHbackendr!   r   r   r   r   r.   k   s    r.   c                   @  r-   )
EquispacedKspaceMaska  
    This k-space mask transform under-samples the k-space according to an
    equi-distant sampling pattern. Precisely, it selects an equi-distant
    subset of columns from the input k-space data. If the k-space data has N
    columns, the mask picks out:

    1. N_low_freqs = (N * center_fraction) columns in the center corresponding
    to low-frequencies

    2. The other columns are selected with equal spacing at a proportion that
    reaches the desired acceleration rate taking into consideration the number
    of low frequencies. This ensures that the expected number of columns
    selected is equal to (N / acceleration)

    It is possible to use multiple center_fractions and accelerations, in
    which case one possible (center_fraction, acceleration) is chosen
    uniformly at random each time the EquispacedMaskFunc object is called.

    Example:
        If accelerations = [4, 8] and center_fractions = [0.08, 0.04],
        then there is a 50% probability that 4-fold acceleration with 8%
        center fraction is selected and a 50% probability that 8-fold
        acceleration with 4% center fraction is selected.

    Modified and adopted from:
        https://github.com/facebookresearch/fastMRI/tree/master/fastmri
    r   r	   r   r   c                 C  sR  t |}|j}|d }| jr|d }|  \}}tt|| }tj|tjd}|| d d }	d||	|	| < |||  || |  }
| j	
dt|
}t||d |
}t|tj}d||< dd	 |D }| jrr||d< n||d< t|j| tj}|| }t|}|| _ttt|| j| jd
}tt|| j d d}||fS )a  
        Args:
            kspace: The input k-space data. The shape is (...,num_coils,H,W,2)
                for complex 2D inputs and (...,num_coils,H,W,D) for real 3D
                data. The last spatial dim is selected for sampling. For the
                fastMRI multi-coil dataset, k-space has the form
                (...,num_slices,num_coils,H,W) and sampling is done along W.
                For a general 3D data with the shape (...,num_coils,H,W,D),
                sampling is done along D.

        Returns:
            A tuple containing
                (1) the under-sampled kspace
                (2) absolute value of the inverse fourier of the under-sampled kspace
        r/   r0   )dtyper2   r   Tr   c                 S  r3   r4   r   r5   r   r   r   r8     r9   z1EquispacedKspaceMask.__call__.<locals>.<listcomp>r:   r;   )r   r=   r   r'   r   r>   rB   zerosrC   r"   r#   arangearoundrA   uintr   r@   rD   r   r
   r   r   )r   r   rE   rF   rG   r%   r&   rH   rD   rJ   Zadjusted_acceloffsetZaccel_samplesrK   rL   rM   rN   rO   r   r   r   r!      s<   
zEquispacedKspaceMask.__call__Nr(   rP   r   r   r   r   rS      s    rS   )
__future__r   abcr   collections.abcr   numpyrB   torchr   Z'monai.apps.reconstruction.complex_utilsr   r   Z#monai.apps.reconstruction.mri_utilsr   monai.config.type_definitionsr	   Zmonai.data.fft_utilsr
   monai.transforms.transformr   monai.utils.enumsr   monai.utils.type_conversionr   r   r.   rS   r   r   r   r   <module>   s   NY