o
    iDk                     @  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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/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 e6d\Z7Z8e6d\Z9Z8e6d\Z:Z8e6ddd\Z;Z<g dZ=e%e e"e#e$e!dZ>d"ddZ?G dd de+Z@G dd de+ZAG d d! d!e+ZBd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MetaKeysOptionalImportErrorconvert_to_dst_typeensure_tuplelook_up_optionoptional_importnibabelz	PIL.ImagenrrdZfilelockFileLockname)	LoadImage	SaveImageSUPPORTED_READERS)ZpydicomreaderZ	itkreaderZ
nrrdreaderZnumpyreaderZ	pilreaderZnibabelreader<c                   sN  t | tjr#| j}| j}tt|   	  
|j|d} | S t | tjr[tjdkr0dnd}| jjdvr:|n| jj} dvrJtd  d| krY|  | j } | S t | trmt fdd	| D } | S t | tr} fd
d| D } | S t | tr fdd|  D } | S t | tttttdfst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 [/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/transforms/io/array.py	<genexpr>c   s    z$switch_endianness.<locals>.<genexpr>c                   s   g | ]}t | qS r6   r/   r1   r4   r6   r7   
<listcomp>e   s    z%switch_endianness.<locals>.<listcomp>c                   s   i | ]
\}}|t | qS r6   r/   )r2   kvr4   r6   r7   
<dictcomp>g   s    z%switch_endianness.<locals>.<dictcomp>NzUnknown type: ) 
isinstancetorchTensordevicer*   
from_numpyr0   cpudetachnumpytorequires_grad_npndarraysys	byteorderdtypeNotImplementedErrorbyteswapviewnewbyteordertuplelistdictitemsboolstrfloatinttypeRuntimeError__name__)datar5   r@   r*   Z
sys_nativeZcurrent_r6   r4   r7   r0   J   s:   	


r0   c                   @  sD   e Zd ZdZddejdddddfdddZdddZ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-   
image_onlyrT   rK   DtypeLike | Noneensure_channel_firstsimple_keysprune_meta_pattern
str | Noneprune_meta_seprU   
expanduserreturnNonec	                 O  s  |du | _ || _|| _|| _|| _|| _|| _|| _g | _t	D ]J}z| 
t	| |	i |
 W q tyF   t| jjd| d Y q tyi   t| jj| d|	 d|
 d | 
t	|   Y qw |du rpdS t|D ]r}t|trtd| d\}}|st| }|du rt| t	}z| 
||	i |
 W qt ty   td| d Y qt ty   t| d|	 d|
 d | 
|  Y qtw t|r| 
||	i |
 qt| 
| qtd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.datar$   )auto_selectr\   rK   r^   r_   patternseprc   readersr(   registerr   logging	getLogger	__class__rZ   debug	TypeErrorr   r=   rU   r    r   r   lowerwarningswarninspectisclass)selfreaderr\   rK   r^   r_   r`   rb   rc   argskwargsr_rZ
the_readerhas_built_inr6   r6   r7   __init__   sZ   
/




zLoadImage.__init__rx   r   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)r=   r   rs   rt   rX   rk   append)rw   rx   r6   r6   r7   rl      s   
zLoadImage.registerfilenameSequence[PathLike] | PathLikeImageReader | Nonec           	        s  t  fddt|D }dg }}|dur||}n\ jddd D ]S} jr6||r5||} nCq$z||}W n7 tyt } z+|t	  t
 jjj|dd t
 jj|jj d| d W Y d}~q$d}~ww g } |du s|du rt|trt|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&fS |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.   )rc   r   )r2   srw   r6   r7   r8      s    
z%LoadImage.__call__.<locals>.<genexpr>NTexc_infoz: unable to load .
   r   
c                 S     g | ]}| qS r6   r6   r2   er6   r6   r7   r9         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: )dstrK   z%`meta_data` must be a dict, got type r-   r)   )ri   rj   )'rP   r   readrk   rh   Zverify_suffix	Exceptionr   	traceback
format_excrm   rn   ro   rZ   rp   infor=   r   lenjoinrY   get_datar   rK   rR   
ValueErrorrX   r0   r   FILENAME_OR_OBJr   ensure_torch_and_prune_metar_   ri   rj   r^   r   r\   meta)	rw   r   rx   imgerrr   msgZ	img_array	meta_datar6   r   r7   __call__   sb   





zLoadImage.__call__)r\   rT   rK   r]   r^   rT   r_   rT   r`   ra   rb   rU   rc   rT   rd   re   )rx   r   r.   )r   r   rx   r   )	rZ   
__module____qualname____doc__rG   float32r~   rl   r   r6   r6   r6   r7   r&   m   s    
^r&   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d5d)d*Z	d6d+d,Z
	d7d8d3d4ZdS )9r'   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   
output_dirr	   output_postfixrU   
output_extoutput_dtyper]   resamplerT   modepadding_modescale
int | NonerK   r   squeeze_end_dimsdata_root_dirseparate_folder	print_logoutput_formatwriter+type[image_writer.ImageWriter] | str | Nonechannel_dimoutput_name_formatter(Callable[[dict, Transform], dict] | Nonefolder_layoutFolderLayoutBase | Nonesavepath_in_metadictrd   re   c                 C  sn  |  |d u rt ||||d|d| _n|| _|  |d u rt| _n|| _| p)| | _| jr:| jds:d| j n| j| _t|trat	d| d\}}|sSt
| }|d u r_td| d|}|d u rkt| jn|f| _d | _|}| jdkr|tjtjd fvrtj}| jd	kr|tjtjd fvrtj}||d
| _|
|d| _||||	d| _d|i| _d| _|| _d S )NT)r   postfix	extensionparentmakedirsr   r-   rg   r$   zwriter z
 not foundz.pngz.dcm)r   r   )r   r   )r   r   r   rK   verboser   )r   r   r   fname_formatterrr   r   
startswithr=   rU   r    r   r   r
   resolve_writerwriters
writer_objrG   uint8uint16init_kwargsdata_kwargsmeta_kwargswrite_kwargs_data_indexr   )rw   r   r   r   r   r   r   r   r   rK   r   r   r   r   r   r   r   r   r   r   Zwriter_r}   _output_dtyper6   r6   r7   r~     sL   
	"



zSaveImage.__init__c                 C  sT   |dur
| j | |dur| j| |dur| j| |dur(| 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   )rw   r   r   r   r   r6   r6   r7   set_options  s   zSaveImage.set_optionsr   torch.Tensor | np.ndarrayr   dict | Noner   str | PathLike | Nonec                 C  s  t |tr|jn|}|dur| | j }n| || }| jjdi |}|rZt|dd}t	|t	|j
kr>d| jd< nt| jdrZtd|j
 d| d| jd d g }| jD ]}}z-|di | j}|jdd	|i| j |jdd
|i| j |j|fi | j || _W n7 ty }	 z+|t  t| jjj|	dd t| jj |jj d| d W Y d}	~	q_d}	~	ww |  j!d7  _!| j"r|dur||t#j$< |  S d%dd |D }
t&| jj d| d| j d| j d|
 	)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_shaper6   r   zdata shape z (with spatial shape z() but SaveImage `channel_dim` is set to z no channel.Z
data_array	meta_dictTr   z: unable to write r   r   r   c                 S  r   r6   r6   r   r6   r6   r7   r9     r   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: )'r=   r   r   r   r   r   r   r   getr   shaper   r   rs   rt   r   r   Zset_data_arrayZset_metadatar   writer   r   r   r   r   r   rm   rn   ro   rZ   rp   r   r   r   r   SAVED_TOr   rY   )rw   r   r   r   kwZmeta_spatial_shaper   Z
writer_clsr   r   r   r6   r6   r7   r     sZ   




zSaveImage.__call__)(r   r	   r   rU   r   rU   r   r]   r   rT   r   rU   r   rU   r   r   rK   r   r   rT   r   r	   r   rT   r   rT   r   rU   r   r   r   r   r   r   r   r   r   rT   rd   re   )NNNN)NN)r   r   r   r   r   r   )rZ   r   r   r   rG   r   r   BORDERfloat64r~   r   r   r6   r6   r6   r7   r'   4  s2    L
Cr'   c                   @  s.   e Zd ZdZddddZdd	d
Zdd ZdS )WriteFileMappingaB  
    Writes a JSON file that logs the mapping between input image paths and their corresponding output paths.
    This class uses FileLock to ensure safe writing to the JSON file in a multiprocess environment.

    Args:
        mapping_file_path (Path or str): Path to the JSON file where the mappings will be saved.
    mapping.jsonmapping_file_path
Path | strc                 C  s   t || _d S r.   )r   r   )rw   r   r6   r6   r7   r~     s   zWriteFileMapping.__init__r   r   c                 C  s   t |tr|j}tj|vrtd|tj }|tj }||d}trCt	t
| jd  | | W d   |S 1 s<w   Y  |S | | |S )zG
        Args:
            img: The input image with metadata.
        z\Missing 'saved_to' key in metadata. Check SaveImage argument 'savepath_in_metadict' is True.)inputoutputz.lockN)r=   r   r   r   r   KeyErrorr   r   has_filelockr#   rU   r   _write_to_file)rw   r   r   Z
input_pathZoutput_pathlog_datar6   r6   r7   r     s$   






zWriteFileMapping.__call__c              	   C  s   z| j d}t|}W d    n1 sw   Y  W n ttjfy+   g }Y nw || | j d}tj||dd W d    d S 1 sKw   Y  d S )Nr{   w   )indent)r   openjsonloadFileNotFoundErrorJSONDecodeErrorr   dump)rw   r   fZexisting_log_datar6   r6   r7   r   3  s   
"zWriteFileMapping._write_to_fileN)r   )r   r   )r   r   )rZ   r   r   r   r~   r   r   r6   r6   r6   r7   r     s
    
r   )r)   )Cr   
__future__r   ru   r   rm   rI   r   rs   collections.abcr   pathlibr   pydocr   typingr   rD   rG   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"   r#   r   __all__r(   r0   r&   r'   r   r6   r6   r6   r7   <module>   sR   
$	(

# H \