U
    Ph$d                     @  s  d Z ddlmZ ddlZddlZddlZddlZddlZddlm	Z	 ddl
mZ ddlmZ ddlmZ ddl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mZmZm Z m!Z!m"Z"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/Z0 ddl-m1Z1m2Z2m3Z3m4Z4m5Z5 e5d\Z6Z7e5d\Z8Z7e5d\Z9Z7dddgZ:e$ee!e"e#e dZ;dddZ<G dd de*Z=G dd de*Z>dS ) z8
A collection of "vanilla" transforms for IO functions.
    )annotationsN)Sequence)Path)locate)Callable)	DtypeLikeNdarrayOrTensorPathLike)image_writer)FolderLayoutFolderLayoutBasedefault_name_formatter)ImageReader	ITKReaderNibabelReader
NrrdReaderNumpyReader	PILReaderPydicomReader)
MetaTensor)is_no_channel)	Transform)EnsureChannelFirst)GridSamplePadMode)ImageMetaKey)OptionalImportErrorconvert_to_dst_typeensure_tuplelook_up_optionoptional_importnibabelz	PIL.Imagenrrd	LoadImage	SaveImageSUPPORTED_READERS)ZpydicomreaderZ	itkreaderZ
nrrdreaderZnumpyreaderZ	pilreaderZnibabelreader<c                   s@  t | tjrD| j}| j}tt|   	  
|j|d} nt | tjrtjdkr^dnd}| jjdkrr|n| jj} dkrtd  d| kr|   } nt | trt fdd	| D } npt | tr fd
d| D } nRt | tr fdd|  D } n.t | tttttdfs<tdt| j | S )z
    Convert the input `data` endianness to `new`.

    Args:
        data: input to be converted.
        new: the target endianness, currently support "<" or ">".
    )requires_gradlittler%   >)r%   r(   zNot implemented option new=.c                 3  s   | ]}t | V  qd S Nswitch_endianness.0xnew N/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/transforms/io/array.py	<genexpr>[   s     z$switch_endianness.<locals>.<genexpr>c                   s   g | ]}t | qS r2   r+   r-   r0   r2   r3   
<listcomp>]   s     z%switch_endianness.<locals>.<listcomp>c                   s   i | ]\}}|t | qS r2   r+   )r.   kvr0   r2   r3   
<dictcomp>_   s      z%switch_endianness.<locals>.<dictcomp>NzUnknown type: )
isinstancetorchTensordevicer&   
from_numpyr,   cpudetachnumpytorequires_grad_npndarraysys	byteorderdtypeNotImplementedErrorbyteswapnewbyteordertuplelistdictitemsboolstrfloatinttypeRuntimeError__name__)datar1   r<   r&   Z
sys_nativeZcurrent_r2   r0   r3   r,   B   s2    

r,   c                
   @  s`   e Zd ZdZddejdddddfdddddd	dd
dddZddddZddddddZdS )r"   a  
    Load image file or files from provided path based on reader.
    If reader is not specified, this class automatically chooses readers
    based on the supported suffixes and in the following order:

        - User-specified reader at runtime when calling this loader.
        - User-specified reader in the constructor of `LoadImage`.
        - Readers from the last to the first in the registered list.
        - Current default readers: (nii, nii.gz -> NibabelReader), (png, jpg, bmp -> PILReader),
          (npz, npy -> NumpyReader), (nrrd -> NrrdReader), (DICOM file -> ITKReader).

    Please note that for png, jpg, bmp, and other 2D formats, readers by default swap axis 0 and 1 after
    loading the array with ``reverse_indexing`` set to ``True`` because the spatial axes definition
    for non-medical specific file formats is different from other common medical packages.

    See also:

        - tutorial: https://github.com/Project-MONAI/tutorials/blob/master/modules/load_medical_images.ipynb

    NTFr)   rO   DtypeLike | Nonez
str | NonerP   None)
image_onlyrG   ensure_channel_firstsimple_keysprune_meta_patternprune_meta_sep
expanduserreturnc	                 O  s  |dk| _ || _|| _|| _|| _|| _|| _|| _g | _t	D ]}z| 
t	| |	|
 W q> tk
r   t| jjd| d Y q> tk
r   t| jj| d|	 d|
 d | 
t	|   Y q>X q>|dkrdS t|D ]}t|trtd| d\}}|st| }|dkr4t| t	}z| 
||	|
 W nd tk
rp   td| d Y n> tk
r   t| d|	 d|
 d | 
|  Y nX qt|r| 
||	|
 q| 
| qdS )	a	  
        Args:
            reader: reader to load image file and metadata
                - if `reader` is None, a default set of `SUPPORTED_READERS` will be used.
                - if `reader` is a string, it's treated as a class name or dotted path
                (such as ``"monai.data.ITKReader"``), the supported built-in reader classes are
                ``"ITKReader"``, ``"NibabelReader"``, ``"NumpyReader"``, ``"PydicomReader"``.
                a reader instance will be constructed with the `*args` and `**kwargs` parameters.
                - if `reader` is a reader class/instance, it will be registered to this loader accordingly.
            image_only: if True return only the image MetaTensor, otherwise return image and header dict.
            dtype: if not None convert the loaded image to this data type.
            ensure_channel_first: if `True` and loaded both image array and metadata, automatically convert
                the image array shape to `channel first`. default to `False`.
            simple_keys: whether to remove redundant metadata keys, default to False for backward compatibility.
            prune_meta_pattern: combined with `prune_meta_sep`, a regular expression used to match and prune keys
                in the metadata (nested dictionary), default to None, no key deletion.
            prune_meta_sep: combined with `prune_meta_pattern`, used to match and prune keys
                in the metadata (nested dictionary). default is ".", see also :py:class:`monai.transforms.DeleteItemsd`.
                e.g. ``prune_meta_pattern=".*_code$", prune_meta_sep=" "`` removes meta keys that ends with ``"_code"``.
            expanduser: if True cast filename to Path and call .expanduser on it, otherwise keep filename as is.
            args: additional parameters for reader if providing a reader name.
            kwargs: additional parameters for reader if providing a reader name.

        Note:

            - The transform returns a MetaTensor, unless `set_track_meta(False)` has been used, in which case, a
              `torch.Tensor` will be returned.
            - If `reader` is specified, the loader will attempt to use the specified readers and the default supported
              readers. This might introduce overheads when handling the exceptions of trying the incompatible loaders.
              In this case, it is therefore recommended setting the most appropriate reader as
              the last item of the `reader` parameter.

        Nzrequired package for reader z< is not installed, or the version doesn't match requirement.z, is not supported with the given parameters  r)   
monai.dataname)auto_selectrY   rG   rZ   r[   patternsepr^   readersr$   registerr   logging	getLogger	__class__rU   debug	TypeErrorr   r9   rP   r   r   r   lowerwarningswarninspectisclass)selfreaderrY   rG   rZ   r[   r\   r]   r^   argskwargsr_rZ
the_readerhas_built_inr2   r2   r3   __init__{   sV    /




zLoadImage.__init__r   )rt   c                 C  s0   t |ts tdt| d | j| dS )z
        Register image reader to load image file and metadata.

        Args:
            reader: reader instance to be registered with this loader.

        z:Preferably the reader should inherit ImageReader, but got r)   N)r9   r   ro   rp   rS   rg   append)rs   rt   r2   r2   r3   rh      s    
zLoadImage.registerzSequence[PathLike] | PathLikezImageReader | None)filenamert   c           	        s  t  fddt|D }dg  }}|dk	r8||}n jddd D ]} jrl||r||} qqHz||}W nl tk
r } zN|t	  t
 jjj|dd t
 jj|jj d| d W 5 d}~X Y qHX g } qqH|dks|dkr`t|tr(t|d	kr(|d
 }ddd |D }t jj d| d j d| ||\}}t|| jdd
 }t|tstdt| dt|d}t|d
  |tj< tj|| j  j! j"d} j#rt$ |} j%r|S |t|tr|j&n|fS )a  
        Load image file and metadata from the given filename(s).
        If `reader` is not specified, this class automatically chooses readers based on the
        reversed order of registered readers `self.readers`.

        Args:
            filename: path file or file-like object or a list of files.
                will save the filename to meta_data with key `filename_or_obj`.
                if provided a list of files, use the filename of first file to save,
                and will stack them together as multi-channels data.
                if provided directory path instead of file path, will treat it as
                DICOM images series and read.
            reader: runtime reader to load image file and metadata.

        c                 3  s&   | ]} j rt|   n|V  qd S r*   )r^   r   )r.   srs   r2   r3   r4      s    z%LoadImage.__call__.<locals>.<genexpr>NTexc_infoz: unable to load .
   r   
c                 S  s   g | ]
}| qS r2   r2   r.   er2   r2   r3   r5     s     z&LoadImage.__call__.<locals>.<listcomp>z) cannot find a suitable reader for file: z.
    Please install the reader libraries, see also the installation instructions:
    https://docs.monai.io/en/latest/installation.html#installing-the-recommended-dependencies.
   The current registered: )dstrG   z%`meta_data` must be a dict, got type r)   r%   )re   rf   )'rK   r   readrg   rd   Zverify_suffix	Exceptionr{   	traceback
format_excri   rj   rk   rU   rl   infor9   r   lenjoinrT   get_datar   rG   rM   
ValueErrorrS   r,   KeyFILENAME_OR_OBJr   ensure_torch_and_prune_metar[   re   rf   rZ   r   rY   meta)	rs   r|   rt   imgerrr   msgZ	img_array	meta_datar2   r~   r3   __call__   s\    



    
zLoadImage.__call__)N)	rU   
__module____qualname____doc__rC   float32rz   rh   r   r2   r2   r2   r3   r"   e   s   ^c                   @  s   e Zd ZdZdddejddejdejdd	ddd	dd
dddfdddddddddddddddddddddddZ	d ddZ
d!ddddddZdS )"r#   a  
    Save the image (in the form of torch tensor or numpy ndarray) and metadata dictionary into files.

    The name of saved file will be `{input_image_name}_{output_postfix}{output_ext}`,
    where the `input_image_name` is extracted from the provided metadata dictionary.
    If no metadata provided, a running index starting from 0 will be used as the filename prefix.

    Args:
        output_dir: output image directory.
        Handled by ``folder_layout`` instead, if ``folder_layout`` is not ``None``.
        output_postfix: a string appended to all output file names, default to `trans`.
        Handled by ``folder_layout`` instead, if ``folder_layout`` is not ``None``.
        output_ext: output file extension name.
        Handled by ``folder_layout`` instead, if ``folder_layout`` is not ``None``.
        output_dtype: data type (if not None) for saving data. Defaults to ``np.float32``.
        resample: whether to resample image (if needed) before saving the data array,
            based on the ``"spatial_shape"`` (and ``"original_affine"``) from metadata.
        mode: This option is used when ``resample=True``. Defaults to ``"nearest"``.
            Depending on the writers, the possible options are

            - {``"bilinear"``, ``"nearest"``, ``"bicubic"``}.
              See also: https://pytorch.org/docs/stable/nn.functional.html#grid-sample
            - {``"nearest"``, ``"linear"``, ``"bilinear"``, ``"bicubic"``, ``"trilinear"``, ``"area"``}.
              See also: https://pytorch.org/docs/stable/nn.functional.html#interpolate

        padding_mode: This option is used when ``resample = True``. Defaults to ``"border"``.
            Possible options are {``"zeros"``, ``"border"``, ``"reflection"``}
            See also: https://pytorch.org/docs/stable/nn.functional.html#grid-sample
        scale: {``255``, ``65535``} postprocess data by clipping to [0, 1] and scaling
            [0, 255] (``uint8``) or [0, 65535] (``uint16``). Default is ``None`` (no scaling).
        dtype: data type during resampling computation. Defaults to ``np.float64`` for best precision.
            if ``None``, use the data type of input data. To set the output data type, use ``output_dtype``.
        squeeze_end_dims: if ``True``, any trailing singleton dimensions will be removed (after the channel
            has been moved to the end). So if input is (C,H,W,D), this will be altered to (H,W,D,C), and
            then if C==1, it will be saved as (H,W,D). If D is also 1, it will be saved as (H,W). If ``False``,
            image will always be saved as (H,W,D,C).
        data_root_dir: if not empty, it specifies the beginning parts of the input file's
            absolute path. It's used to compute ``input_file_rel_path``, the relative path to the file from
            ``data_root_dir`` to preserve folder structure when saving in case there are files in different
            folders with the same file names. For example, with the following inputs:

            - input_file_name: ``/foo/bar/test1/image.nii``
            - output_postfix: ``seg``
            - output_ext: ``.nii.gz``
            - output_dir: ``/output``
            - data_root_dir: ``/foo/bar``

            The output will be: ``/output/test1/image/image_seg.nii.gz``

            Handled by ``folder_layout`` instead, if ``folder_layout`` is not ``None``.
        separate_folder: whether to save every file in a separate folder. For example: for the input filename
            ``image.nii``, postfix ``seg`` and ``folder_path`` ``output``, if ``separate_folder=True``, it will be
            saved as: ``output/image/image_seg.nii``, if ``False``, saving as ``output/image_seg.nii``.
            Default to ``True``.
            Handled by ``folder_layout`` instead, if ``folder_layout`` is not ``None``.
        print_log: whether to print logs when saving. Default to ``True``.
        output_format: an optional string of filename extension to specify the output image writer.
            see also: ``monai.data.image_writer.SUPPORTED_WRITERS``.
        writer: a customised ``monai.data.ImageWriter`` subclass to save data arrays.
            if ``None``, use the default writer from ``monai.data.image_writer`` according to ``output_ext``.
            if it's a string, it's treated as a class name or dotted path (such as ``"monai.data.ITKWriter"``);
            the supported built-in writer classes are ``"NibabelWriter"``, ``"ITKWriter"``, ``"PILWriter"``.
        channel_dim: the index of the channel dimension. Default to ``0``.
            ``None`` to indicate no channel dimension.
        output_name_formatter: a callable function (returning a kwargs dict) to format the output file name.
            If using a custom ``monai.data.FolderLayoutBase`` class in ``folder_layout``, consider providing
            your own formatter.
            see also: :py:func:`monai.data.folder_layout.default_name_formatter`.
        folder_layout: A customized ``monai.data.FolderLayoutBase`` subclass to define file naming schemes.
            if ``None``, uses the default ``FolderLayout``.
        savepath_in_metadict: if ``True``, adds a key ``"saved_to"`` to the metadata, which contains the path
            to where the input image has been saved.
    z./transz.nii.gzFnearestNT r   r	   rP   rW   rO   z
int | Noner   z+type[image_writer.ImageWriter] | str | Nonez(Callable[[dict, Transform], dict] | NonezFolderLayoutBase | NonerX   )
output_diroutput_postfix
output_extoutput_dtyperesamplemodepadding_modescalerG   squeeze_end_dimsdata_root_dirseparate_folder	print_logoutput_formatwriterchannel_dimoutput_name_formatterfolder_layoutsavepath_in_metadictr_   c                 C  sv  |  |d kr$t ||||d|d| _n|| _|  |d kr>t| _n|| _| pR| | _| jrt| jdstd| j n| j| _t|trt	d| d\}}|st
| }|d krtd| d|}|d krt| jn|f| _d | _|}| jdkr|tjtjd fkrtj}| jd	kr4|tjtjd fkr4tj}||d
| _|
|d| _||||	d| _d|i| _d| _|| _d S )NT)r   postfix	extensionparentmakedirsr   r)   ra   rb   zwriter z
 not foundz.pngz.dcm)r   r   )r   r   )r   r   r   rG   verboser   )r   r   r   fname_formatterrn   r   
startswithr9   rP   r   r   r   r
   resolve_writerwriters
writer_objrC   uint8uint16init_kwargsdata_kwargsmeta_kwargswrite_kwargs_data_indexr   )rs   r   r   r   r   r   r   r   r   rG   r   r   r   r   r   r   r   r   r   r   Zwriter_ry   _output_dtyper2   r2   r3   rz   w  sL    
	"

  
zSaveImage.__init__c                 C  sT   |dk	r| j | |dk	r(| j| |dk	r<| j| |dk	rP| j| | S )a  
        Set the options for the underlying writer by updating the `self.*_kwargs` dictionaries.

        The arguments correspond to the following usage:

            - `writer = ImageWriter(**init_kwargs)`
            - `writer.set_data_array(array, **data_kwargs)`
            - `writer.set_metadata(meta_data, **meta_kwargs)`
            - `writer.write(filename, **write_kwargs)`

        N)r   updater   r   r   )rs   r   r   r   r   r2   r2   r3   set_options  s    zSaveImage.set_optionsztorch.Tensor | np.ndarrayzdict | Nonezstr | PathLike | None)r   r   r|   c                 C  s  t |tr|jn|}|dk	r,| | j }n| || }| jjf |}|rt|dd}t	|t	|j
krxd| jd< n8t| jdrtd|j
 d| d| jd d g }| jD ]}zR|f | j}|jf d	|i| j |jf d
|i| j |j|f| j || _W nn tk
r~ }	 zN|t  t| jjj|	dd t| jj |jj d| d W 5 d}	~	X Y qX |  j!d7  _!| j"r|dk	r||d< |  S qd#dd |D }
t$| jj d| d| j d| j d|
 	dS )az  
        Args:
            img: target data content that save into file. The image should be channel-first, shape: `[C,H,W,[D]]`.
            meta_data: key-value pairs of metadata corresponding to the data.
            filename: str or file-like object which to save img.
                If specified, will ignore `self.output_name_formatter` and `self.folder_layout`.
        Nspatial_shaper2   r   zdata shape z (with spatial shape z() but SaveImage `channel_dim` is set to z no channel.
data_array	meta_dictTr   z: unable to write r   r   Zsaved_tor   c                 S  s   g | ]
}| qS r2   r2   r   r2   r2   r3   r5     s     z&SaveImage.__call__.<locals>.<listcomp>z# cannot find a suitable writer for z.
    Please install the writer libraries, see also the installation instructions:
    https://docs.monai.io/en/latest/installation.html#installing-the-recommended-dependencies.
   The current registered writers for z: )%r9   r   r   r   r   r   r|   r   getr   shaper   r   ro   rp   r   r   Zset_data_arrayZset_metadatar   writer   r   r   r{   r   r   ri   rj   rk   rU   rl   r   r   r   r   rT   )rs   r   r   r|   kwZmeta_spatial_shaper   Z
writer_clsr   r   r   r2   r2   r3   r     sF    
 


&zSaveImage.__call__)NNNN)NN)rU   r   r   r   rC   r   r   BORDERfloat64rz   r   r   r2   r2   r2   r3   r#   ,  s2   L6C
   )r%   )?r   
__future__r   rq   ri   rE   r   ro   collections.abcr   pathlibr   pydocr   typingr   r@   rC   r:   monai.configr   r   r	   
monai.datar
   Zmonai.data.folder_layoutr   r   r   Zmonai.data.image_readerr   r   r   r   r   r   r   monai.data.meta_tensorr   monai.data.utilsr   monai.transforms.transformr   Zmonai.transforms.utility.arrayr   monai.utilsr   r   r   r   r   r   r   r   nib_Imager!   __all__r$   r,   r"   r#   r2   r2   r2   r3   <module>   sL   $	


# H