
    #j7                     d   d dl Z d dlmZmZ d dlmZ d dlmZmZm	Z	m
Z
mZm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mZmZ dd
lmZmZ er
d dlZddlmZ ej         rd dlZ G d dej!        j"                  Z#e G d d                      Z$dddde%de&e'eee'e(f                  f         fdZ)dS )    N)	dataclassfield)Path)TYPE_CHECKINGAnyClassVarDictOptionalUnion   )config)DownloadConfig)
array_cast)is_local_pathis_remote_urlxopen)no_op_if_value_is_nullstring_to_dict   )FeatureTypec                   B     e Zd ZdZdej        j        f fdZd Z xZ	S )Nifti1ImageWrapperzY
        A wrapper around nibabel's Nifti1Image to customize its representation.
        nifti_imagec           	          t                                          |j        |j        |j        |j        |j        |                                           || _        d S )N)dataobjaffineheaderextrafile_mapdtype)	super__init__r   r   r   r   r   get_data_dtyper   )selfr   	__class__s     a/lsinfo/ai/hellotax_ai/base_platform/venv/lib/python3.11/site-packages/datasets/features/nifti.pyr"   zNifti1ImageWrapper.__init__   sa    GG#+")")!'$-!0022      +D    c                    ddl m}m}m}m} ddlm} | j                                        } |            }|	                    |j
                   |j        |j        _        d|j        _        d|j        _        d }t!          | j        d          rFd| j        j        v r8t%          | j        j        d         dd           | j        j        d         j        }|d} |||	          }	|                    |	g            ||           d S )
Nr   )NiiVue
ShowRender	SliceTypeVolume)displayTr   imagefilenamezvolume.nii.gz)namedata)	ipyniivuer)   r*   r+   r,   IPython.displayr-   r   to_bytesset_slice_typeMULTIPLANARALWAYSoptsmultiplanar_show_rendershow_3d_crosshairmultiplanar_force_renderhasattrr   getattrr/   load_volumes)
r$   r)   r*   r+   r,   r-   bytes_nvr0   volumes
             r&   _repr_html_zNifti1ImageWrapper._repr_html_'   s/   GGGGGGGGGGGG//////%..00FBi3444.8.?BG+(,BG%/3BG,Dt'44 Gt/888 0 9' BJPTUUa+4W=FD|&VF333FOOVH%%%GBKKKKKr'   )
__name__
__module____qualname____doc__nibnifti1Nifti1Imager"   rB   __classcell__)r%   s   @r&   r   r      sb        	 			+
(> 		+ 		+ 		+ 		+ 		+ 		+	 	 	 	 	 	 	r'   r   c            	          e Zd ZU dZdZeed<    edd          Ze	e
         ed<   dZee
         ed	<    ej         ej                     ej                    d
          Zee         ed<    ed dd          Ze
ed<   d Zdee
eeedf         defdZddeddfdZ	 ddej        dededej        fdZdedee
df         f         fdZdeej        ej        ej         f         dej        fdZ!dS )Niftia  
    **Experimental.**
    Nifti [`Feature`] to read NIfTI neuroimaging files.

    Input: The Nifti feature accepts as input:
    - A `str`: Absolute path to the NIfTI file (i.e. random access is allowed).
    - A `pathlib.Path`: path to the NIfTI file (i.e. random access is allowed).
    - A `dict` with the keys:
        - `path`: String with relative path of the NIfTI file in a dataset repository.
        - `bytes`: Bytes of the NIfTI file.
      This is useful for archived files with sequential access.

    - A `nibabel` image object (e.g., `nibabel.nifti1.Nifti1Image`).

    Args:
        decode (`bool`, defaults to `True`):
            Whether to decode the NIfTI data. If `False` a string with the bytes is returned. `decode=False` is not supported when decoding examples.

    Examples:

    ```py
    >>> from datasets import Dataset, Nifti
    >>> ds = Dataset.from_dict({"nifti": ["path/to/file.nii.gz"]}).cast_column("nifti", Nifti())
    >>> ds.features["nifti"]
    Nifti(decode=True, id=None)
    >>> ds[0]["nifti"]
    <nibabel.nifti1.Nifti1Image object at 0x7f8a1c2d8f40>
    >>> ds = ds.cast_column("nifti", Nifti(decode=False))
    >>> ds[0]["nifti"]
    {'bytes': None,
    'path': 'path/to/file.nii.gz'}
    ```
    TdecodeNF)defaultrepridznibabel.nifti1.Nifti1Imager    bytespathpa_type)rN   initrO   _typec                     | j         S N)rT   )r$   s    r&   __call__zNifti.__call__k   s
    |r'   valuenib.Nifti1Imagereturnc                 D   t           j        rddl}nd}t          |t                    r|ddS t          |t
                    r$t	          |                                          ddS t          |t          t          f          rd|dS |)t          ||j	        j
                  rt          |          S t          |t                    r|                    d          =t          j                            |d                   rd|                    d          dS |                    d          |                    d          +|                    d          |                    d          dS t#          d| d          t#          d	t%          |           d          )
zEncode example into a format for Arrow.

        Args:
            value (`str`, `bytes`, `nibabel.Nifti1Image` or `dict`):
                Data passed as input to Nifti feature.

        Returns:
            `dict` with "path" and "bytes" fields
        r   NrS   rR   rS   rQ   rR   zTA nifti sample should have one of 'path' or 'bytes' but they are missing or None in .zPA nifti sample should be a string, bytes, Path, nibabel image, or dict, but got )r   NIBABEL_AVAILABLEnibabel
isinstancestrr   absoluterR   	bytearrayspatialimagesSpatialImageencode_nibabel_imagedictgetosrS   isfile
ValueErrortype)r$   rZ   rG   s      r&   encode_examplezNifti.encode_examplen   s    # 	!!!!!CeS!! 	!D111t$$ 	 0 011DAAAy122 	 5111_E33D3Q!R!R_'...t$$ 	yy  ,f1N1N,!%uyy/@/@AAA7##/599V3D3D3P!&7!3!3UYYv=N=NOOO skpsss   qcghmcncnqqq  r'   r   c                    t           j        rddl}nt          d          |i }|d         |d         }}|Z|t	          d| d          |                    d          rCt          |                    d	          d
                   r|                    d	          d
         }t          |          r |j        |          }n|                    d	          d
         }|                    t           j	                  rt           j
        nt           j        }t          ||          }	|	|                    |	d                   nd}
t          |
          }t          |d|          5 } |j        |          }ddd           n# 1 swxY w Y   nAddl}|dd         dk    r|                    |          }|j                            |          }t)          |          S )a  Decode example NIfTI file into nibabel image object.

        Args:
            value (`str` or `dict`):
                A string with the absolute NIfTI file path, a dictionary with
                keys:

                - `path`: String with absolute or relative NIfTI file path.
                - `bytes`: The bytes of the NIfTI file.

            token_per_repo_id (`dict`, *optional*):
                To access and decode NIfTI files from private repositories on
                the Hub, you can pass a dictionary
                repo_id (`str`) -> token (`bool` or `str`).

        Returns:
            `nibabel.Nifti1Image` objects
        r   Nz:To support decoding NIfTI files, please install 'nibabel'.rS   rR   zBA nifti should have one of 'path' or 'bytes' but both are None in r_   zgzip://::repo_idtokenrbdownload_configr   s   )r   r`   ra   ImportErrorrm   
startswithr   splitloadHF_ENDPOINTHUB_DATASETS_URLHUB_DATASETS_HFFS_URLr   rj   r   r   gzip
decompressrI   
from_bytesr   )r$   rZ   token_per_repo_idrG   rS   r?   nifti
source_urlpatternsource_url_fieldsru   rx   fr   s                 r&   decode_examplezNifti.decode_example   s9   & # 	\!!!!!Z[[[$ "V}eGnf>| !nfk!n!n!nooo ??9-- 0-

4@P@PQS@T2U2U 0::d++B/D && ,$CHTNNEE!%D!1!1"!5J &001CDD://#9 
 )7z7(K(K%O`Ol)--.?	.JKKKrv  '55&A&A&AOtT?KKK ,q (, , , , , , , , , , , , , , , KKK rr
k))00O..v66E!%(((s   )FF
F
storagelocal_filesremote_filesc                    i t           fd            t          j        fd|                                D             t          j                              }t          j        fd|                    d                                          D             t          j                              }t          j                            ||gddg|	                                          }t          || j                  S )	a7  Embed NifTI files into the Arrow array.

        Args:
            storage (`pa.StructArray`):
                PyArrow array to embed.
            token_per_repo_id (`dict`, optional):
                Dictionary repo_id -> token to fetch the files bytes.
            local_files (`bool`, defaults to `True`)
                Whether to embed local files data in the array

                <Added version="4.8.5"/>
            remote_files (`bool`, defaults to `True`)
                Whether to embed remote files data in the array.
                E.g. files with paths that start with hf:// or https://

                <Added version="4.8.5"/>

        Returns:
            `pa.StructArray`: Array in the NifTI arrow storage type, that is
                `pa.struct({"bytes": pa.binary(), "path": pa.string()})`.
        Nc                    |                      d          d         }|                    t          j                  rt          j        nt          j        }t          ||          }|                    |d                   nd }t          |          }t          | d|          5 }|
                                cd d d            S # 1 swxY w Y   d S )Nrq   rr   rs   rt   rv   rw   )r{   rz   r   r}   r~   r   r   rj   r   r   read)rS   r   r   r   ru   rx   r   r   s          r&   path_to_bytesz*Nifti.embed_storage.<locals>.path_to_bytes   s   D))"-J+5+@+@AS+T+Tv''Z`Zv  !/z7 C CK\Kh%))*;I*FGGGnrE,5999OtT?CCC  qvvxx                                   s   %CC
C
c                     g | ]U}|O|d         ?rt          |d                   sr&t          |d                   r |d                   n	|d         nd VS )NrR   rS   )r   r   ).0xr   r   r   s     r&   
<listcomp>z'Nifti.embed_storage.<locals>.<listcomp>   s     
 
 
  =	 z)% **7&	*B*B *HT *YfghiogpYqYq * "M!F),,, 7 
 
 
r'   rn   c                     g | ]I}|Crt          |          sr.t          |          rt          j                            |          n|nd JS rX   )r   r   rk   rS   basename)r   rS   r   r   s     r&   r   z'Nifti.embed_storage.<locals>.<listcomp>  s     	 	 	  # $(5d(;(;AMR_`dReReBG$$T*** 	 	 	r'   rS   rR   mask)r   paarray	to_pylistbinaryr   stringStructArrayfrom_arraysis_nullr   rT   )r$   r   r   r   r   bytes_array
path_arrayr   s     ```  @r&   embed_storagezNifti.embed_storage   sI   0 $ "			  		  		  		  
 			  h
 
 
 
 
 
 !**,,
 
 
 
 
 
 X	 	 	 	 	 $MM&11;;==	 	 	 
 
 

 .,,k:-FRXHY`g`o`o`q`q,rr'4<000r'   r   c                 N    ddl m} | j        r| n |d           |d          dS )zfIf in the decodable state, return the feature itself, otherwise flatten the feature into a dictionary.r   )Valuer   r   rQ   )featuresr   rM   )r$   r   s     r&   flattenzNifti.flatten  sK    ###### {DD xh 	
r'   c                    t           j                            |j                  rrt          j        dgt          |          z  t          j                              }t           j                            ||gddg|	                                          }nt           j        
                    |j                  rrt          j        dgt          |          z  t          j                              }t           j                            ||gddg|	                                          }n5t           j                            |j                  r|j                            d          dk    r|                    d          }n8t          j        dgt          |          z  t          j                              }|j                            d          dk    r|                    d          }n8t          j        dgt          |          z  t          j                              }t           j                            ||gddg|	                                          }t          || j                  S )a  Cast an Arrow array to the Nifti arrow storage type.
        The Arrow types that can be converted to the Nifti pyarrow storage type are:

        - `pa.string()` - it must contain the "path" data
        - `pa.binary()` - it must contain the NIfTI bytes
        - `pa.struct({"bytes": pa.binary()})`
        - `pa.struct({"path": pa.string()})`
        - `pa.struct({"bytes": pa.binary(), "path": pa.string()})`  - order doesn't matter

        Args:
            storage (`Union[pa.StringArray, pa.StructArray, pa.BinaryArray]`):
                PyArrow array to cast.

        Returns:
            `pa.StructArray`: Array in the Nifti arrow storage type, that is
                `pa.struct({"bytes": pa.binary(), "path": pa.string()})`.
        Nr   rR   rS   r   r   )r   types	is_stringrn   r   lenr   r   r   r   	is_binaryr   	is_structget_field_indexr   r   rT   )r$   r   r   r   s       r&   cast_storagezNifti.cast_storage'  s   $ 8gl++ 	w(D6CLL#8ry{{KKKKn00+w1G'SYIZahapaparar0ssGGX-- 	w4&3w<<"7bikkJJJJn00':1FRXHY`g`o`o`q`q0rrGGX-- 		w|++G4499%mmG44 hvG'<29;;OOO|++F33q88$]]622

Xtfs7||&;")++NNN
n00+z1JWV\L]dkdsdsdudu0vvG'4<000r'   rX   )NTT)"rC   rD   rE   rF   rM   bool__annotations__r   rP   r
   rc   r    r   r   structr   r   rT   r   rV   rY   r   rR   re   ri   ro   r   r   r   r	   r   StringArrayBinaryArrayr    r'   r&   rL   rL   ?   s           D FDd777B777 8E8C=777&RYibikk'R'RSSGXc]SSSwU???E3???  &E#uiGX*X$Y &^b & & & &P=) =)D =)EY =) =) =) =)@ osC1 C1~C1LPC1gkC1	C1 C1 C1 C1J
}d33E.FFG 
 
 
 
"1E".".".*X$Y "1^`^l "1 "1 "1 "1 "1 "1r'   rL   Fimgr[   force_bytesr\   c                     t          | d          r | j        |s| j        d         j        }|ddS |                                 }d|dS )a  
    Encode a nibabel image object into a dictionary.

    If the image has an associated file path, returns the path. Otherwise, serializes
    the image content into bytes.

    Args:
        img: A nibabel image object (e.g., Nifti1Image).
        force_bytes: If `True`, always serialize to bytes even if a file path exists. Needed to upload bytes properly.

    Returns:
        dict: A dictionary with "path" or "bytes" field.
    r   Nr.   r^   )r<   r   r/   r4   )r   r   r/   
bytes_datas       r&   rh   rh   L  sZ     sJ 1CL$<[$<<(1 4000J:...r'   )F)*rk   dataclassesr   r   pathlibr   typingr   r   r   r	   r
   r   pyarrowr    r   download.download_configr   tabler   utils.file_utilsr   r   r   utils.py_utilsr   r   ra   rG   r   r   r`   rH   rI   r   rL   r   ri   rc   rR   rh   r   r'   r&   <module>r      s   				 ( ( ( ( ( ( ( (       F F F F F F F F F F F F F F F F           5 5 5 5 5 5       B B B B B B B B B B C C C C C C C C  &%%%%%%	 (% % % % %SZ3 % % %P I1 I1 I1 I1 I1 I1 I1 I1X/ // /d /tTWYabghkmrhrbsYtTtOu / / / / / /r'   