U
    Cvf05                     @  s8  d dl mZ d dlZd dlZd dlZd dlmZ d dlmZm	Z	m
Z
mZmZ d dlmZmZ d dlmZmZmZmZ d dl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 m!Z!m"Z"m#Z#m$Z$ d dl%m&Z& G dd deZ'dd Z(dd Z)ej*edddddZ+dd Z,G dd de
Z-G dd de	Z.e.ed< dS )    )annotationsN)Version)BACKEND_ENTRYPOINTSBackendEntrypointWritableCFDataStore_normalize_pathfind_root_and_group)CachingFileManagerDummyFileManager)	HDF5_LOCKcombine_locksensure_lockget_write_lock)BaseNetCDF4Array_encode_nc4_variable_extract_nc4_variable_encoding_get_datatype_nc4_require_group)StoreBackendEntrypoint)indexing)
FrozenDictis_remote_urimodule_availableread_magic_number_from_file'try_read_magic_number_from_file_or_path)Variablec                   @  s&   e Zd Zd	ddZdd Zdd ZdS )
H5NetCDFArrayWrapperTc                 C  s   | j |}|j| j S N)	datastore_acquire	variablesZvariable_name)self
needs_lockds r$   =/tmp/pip-unpacked-wheel-h316xyqg/xarray/backends/h5netcdf_.py	get_array&   s    zH5NetCDFArrayWrapper.get_arrayc                 C  s   t || jt jj| jS r   )r   Zexplicit_indexing_adaptershapeZIndexingSupportZOUTER_1VECTOR_getitem)r!   keyr$   r$   r%   __getitem__*   s       z H5NetCDFArrayWrapper.__getitem__c              
   C  s4   | j j" | jdd}|| W  5 Q R  S Q R X d S )NF)r"   )r   lockr&   )r!   r)   arrayr$   r$   r%   r(   /   s    
zH5NetCDFArrayWrapper._getitemN)T)__name__
__module____qualname__r&   r*   r(   r$   r$   r$   r%   r   %   s   
r   c                 C  s   t | tr| dS | S d S )Nzutf-8)
isinstancebytesdecode)txtr$   r$   r%   maybe_decode_bytes5   s    

r4   c                 C  s4   i }| j  D ] \}}|dkr&t|}|||< q|S )N)
_FillValueZmissing_value)attrsitemsr4   )Zh5netcdf_varr6   kvr$   r$   r%   _read_attributes<   s    
r:   FTh5netcdf)Zlsd_okayZ	h5py_okaybackendunlimited_dimsc                 C  s
   |  |S r   Zcreate_group)Zdatasetnamer$   r$   r%   _h5netcdf_create_groupQ   s    r@   c                	   @  s   e Zd ZdZdZddedfddZed%d	d
Zd&ddZ	e
dd Zdd Zdd Zdd Zdd Zdd Zd'ddZdd Zdd Zd(dd Zd!d" Zd#d$ ZdS ))H5NetCDFStorez/Store for reading and writing data via h5netcdf)	autocloseformat	is_remoter+   	_filename_group_manager_modeNFc                 C  s   dd l }t||j|jfrR|d kr0t|\}}nt||jk	rFtd|}t|}|| _|| _	|| _
d | _t| jd j| _t| j| _t|| _|| _d S )Nr   z=must supply a h5netcdf.File if the group argument is provided)r;   r0   FileGroupr   type
ValueErrorr
   rG   rF   rH   rC   r#   filenamerE   r   rD   r   r+   rB   )r!   managergroupmoder+   rB   r;   rootr$   r$   r%   __init__c   s$    
zH5NetCDFStore.__init__rTc
                 C  s   dd l }
t|trtdn,t|tjrHt|}|dsHt| d|dkrXtdd|i}|d k	rp||d< t|
j	td	krt|
j
jj	td
kr|	|d< |d kr|dkrt}nttt|g}t|
j|||d}| |||||dS )Nr   zGcan't open netCDF4/HDF5 as bytes try passing a path or file-like object   HDF

z- is not the signature of a valid netCDF4 file)NZNETCDF4z#invalid format for h5netcdf backendinvalid_netcdf
phony_dimsz0.10.0z3.0.0decode_vlen_stringsrS   )rP   kwargs)rO   rP   r+   rB   )r;   r0   r1   rL   ioIOBaser   
startswithr   __version__coreh5pyr   r   r   r	   rI   )clsrM   rP   rC   rO   r+   rB   rU   rV   rW   r;   magic_numberrX   rN   r$   r$   r%   open}   s8    

zH5NetCDFStore.openc              	   C  s0   | j |}t|| j| jtd}W 5 Q R X |S )Nr>   )rG   Zacquire_contextr   rF   rH   r@   )r!   r"   rQ   r#   r$   r$   r%   r      s       zH5NetCDFStore._acquirec                 C  s   |   S r   )r   r!   r$   r$   r%   r#      s    zH5NetCDFStore.dsc           	      C  s   dd l }|j}tt|| }t|}|j|j|jd}|j	dkrVd|d< |j
|d< n|j	d k	rt|j	|d< |j
|d< | j|d	< |j|d
< |j|jd}|tkrt|d< n|d k	rn
|j|d< t||||S )Nr   )
chunksizes
fletcher32shufflegzipTzlib	complevelcompressioncompression_optssourceZoriginal_shapeZvlendtype)r^   
dimensionsr   ZLazilyIndexedArrayr   r:   chunksrd   re   ri   rj   rE   r'   Zcheck_dtyperm   strr   )	r!   r?   varr^   rn   datar6   encodingZ
vlen_dtyper$   r$   r%   open_store_variable   s.    







z!H5NetCDFStore.open_store_variablec                   s   t  fdd jj D S )Nc                 3  s"   | ]\}}|  ||fV  qd S r   )rt   .0r8   r9   rb   r$   r%   	<genexpr>   s    z.H5NetCDFStore.get_variables.<locals>.<genexpr>)r   r#   r    r7   rb   r$   rb   r%   get_variables   s    
zH5NetCDFStore.get_variablesc                 C  s   t t| jS r   )r   r:   r#   rb   r$   r$   r%   	get_attrs   s    zH5NetCDFStore.get_attrsc                 C  s@   dd l }t|jtdkr4tdd | jj D S | jjS d S )Nr   0.14.0.dev0c                 s  s   | ]\}}|t |fV  qd S r   )lenru   r$   r$   r%   rw      s     z/H5NetCDFStore.get_dimensions.<locals>.<genexpr>)r;   r   r\   r   r#   rn   r7   r!   r;   r$   r$   r%   get_dimensions   s    zH5NetCDFStore.get_dimensionsc                 C  sR   dd l }t|jtdkr4ddd | jj D iS ddd | jj D iS d S )Nr   rz   r=   c                 S  s   h | ]\}}|  r|qS r$   )Zisunlimitedru   r$   r$   r%   	<setcomp>   s     z-H5NetCDFStore.get_encoding.<locals>.<setcomp>c                 S  s   h | ]\}}|d kr|qS r   r$   ru   r$   r$   r%   r~      s     )r;   r   r\   r#   rn   r7   r|   r$   r$   r%   get_encoding   s     
 
zH5NetCDFStore.get_encodingc                 C  s0   |r d | j j|< | j || n|| j j|< d S r   )r#   rn   Zresize_dimension)r!   r?   lengthZis_unlimitedr$   r$   r%   set_dimension   s    zH5NetCDFStore.set_dimensionc                 C  s   || j j|< d S r   )r#   r6   )r!   r)   valuer$   r$   r%   set_attribute  s    zH5NetCDFStore.set_attributec                 C  s   t |S r   )r   )r!   variabler$   r$   r%   encode_variable  s    zH5NetCDFStore.encode_variablec                 C  s  dd l }|j }t||d}|dd }|tkrJ|d k	rJtd|d|tkr^|jtd}t||d}	i }
|	dd	r|r|		d
dkrt
d|	d
d |rd|	krd|	kr|	d |	d krt
d|	dd}|dkr|	d| |	dd |	d< |jr&dD ]}||	kr|	| |
|< q|| jkrR| jj|f||j|d|
}n
| j| }| D ]\}}||j|< qdt|| }||jfS )Nr   )Zraise_on_invalid_encodingr5   zh5netcdf does not yet support setting a fill value for variable-length strings (https://github.com/h5netcdf/h5netcdf/issues/37). Either remove '_FillValue' from encoding on variable zH or set {'dtype': 'S1'} in encoding to use the fixed width NC_CHAR type.rl   )Zraise_on_invalidrg   Fri   )Nrf   z+'zlib' and 'compression' encodings mismatchrf   rh   rj   z5'complevel' and 'compression_opts' encodings mismatchrc   ro   )ri   rj   re   ro   rd   )rm   rn   	fillvalue)r^   r6   copyr   poprp   NotImplementedErrorZspecial_dtype_extract_h5nc_encodinggetrL   
setdefaultr'   r#   Zcreate_variableZdimsr7   r   rr   )r!   r?   r   Zcheck_encodingr=   r^   r6   rm   r   rs   rX   rh   r)   Znc4_varr8   r9   targetr$   r$   r%   prepare_variable	  s`    

	


zH5NetCDFStore.prepare_variablec                 C  s   | j   d S r   )r#   syncrb   r$   r$   r%   r   T  s    zH5NetCDFStore.syncc                 K  s   | j jf | d S r   )rG   close)r!   rX   r$   r$   r%   r   W  s    zH5NetCDFStore.close)rS   NNNFNNT)T)F)FN)r-   r.   r/   __doc__	__slots__r   rR   classmethodra   r   propertyr#   rt   rx   ry   r}   r   r   r   r   r   r   r   r$   r$   r$   r%   rA   U   s:           .

%
   
KrA   c                   @  sN   e Zd ZdZedZdZdZdd Zdddddddddddddd	d
dZ	dS )H5netcdfBackendEntrypointa  
    Backend for netCDF files based on the h5netcdf package.

    It can open ".nc", ".nc4", ".cdf" files but will only be
    selected as the default if the "netcdf4" engine is not available.

    Additionally it can open valid HDF5 files, see
    https://h5netcdf.org/#invalid-netcdf-files for more info.
    It will not be detected as valid backend for such files, so make
    sure to specify ``engine="h5netcdf"`` in ``open_dataset``.

    For more information about the underlying library, visit:
    https://h5netcdf.org

    See Also
    --------
    backends.H5NetCDFStore
    backends.NetCDF4BackendEntrypoint
    backends.ScipyBackendEntrypoint
    r;   zMOpen netCDF (.nc, .nc4 and .cdf) and most HDF5 files using h5netcdf in XarrayzZhttps://docs.xarray.dev/en/stable/generated/xarray.backends.H5netcdfBackendEntrypoint.htmlc                 C  sN   t |}|d k	r|dS ztj|\}}W n tk
rD   Y dS X |dkS )NrT   F>   .nc4.nc.cdf)r   r[   ospathsplitext	TypeError)r!   filename_or_objr`   _extr$   r$   r%   guess_can_openw  s    
z(H5netcdfBackendEntrypoint.guess_can_openTN)mask_and_scaledecode_timesconcat_charactersdecode_coordsdrop_variables
use_cftimedecode_timedeltarC   rO   r+   rU   rV   rW   c             
   C  sD   t |}tj||	|
||||d}t }|j||||||||d}|S )N)rC   rO   r+   rU   rV   rW   )r   r   r   r   r   r   r   )r   rA   ra   r   open_dataset)r!   r   r   r   r   r   r   r   r   rC   rO   r+   rU   rV   rW   storeZstore_entrypointr#   r$   r$   r%   r     s,    

z&H5netcdfBackendEntrypoint.open_dataset)
r-   r.   r/   r   r   	availabledescriptionurlr   r   r$   r$   r$   r%   r   [  s(   r   )/
__future__r   	functoolsrY   r   Zpackaging.versionr   Zxarray.backends.commonr   r   r   r   r   Zxarray.backends.file_managerr	   r
   Zxarray.backends.locksr   r   r   r   Zxarray.backends.netCDF4_r   r   r   r   r   Zxarray.backends.storer   Zxarray.corer   Zxarray.core.utilsr   r   r   r   r   Zxarray.core.variabler   r   r4   r:   partialr   r@   rA   r   r$   r$   r$   r%   <module>   s8   	  U