a
    İaI                     @   s  d dl Z d dlZd dlZd dl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mZ ddlmZ d	d
lmZmZ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#m$Z$ d	dl%m&Z&m'Z' d	dl(m)Z) zd dl*Z*dZ+W n e,y   dZ+Y n0 dddddZ-e"e!e gZ.G dd deZ/G dd de/Z0dd Z1dd Z2d4ddZ3d d! Z4d"d# Z5e5fd$d%Z6d&d' Z7d(d) Z8d5d+d,Z9d-d. Z:G d/d0 d0eZ;G d1d2 d2eZ<e<ed3< dS )6    N)suppress   )coding)pop_to)indexing)
FrozenDictclose_on_erroris_remote_uritry_read_magic_number_from_path)Variable   )BACKEND_ENTRYPOINTSBackendArrayBackendEntrypointWritableCFDataStore_normalize_pathfind_root_and_grouprobust_getitem)CachingFileManagerDummyFileManager)	HDF5_LOCKNETCDFC_LOCKcombine_locksensure_lockget_write_lock)encode_nc3_attr_valueencode_nc3_variable)StoreBackendEntrypointTFnativeZbiglittle)=><|c                   @   s*   e Zd ZdZdd Zdd Zd
ddZd	S )BaseNetCDF4Array)	datastoredtypeshapevariable_namec                 C   s>   || _ || _|  }|j| _|j}|tu r4td}|| _d S )NO)r%   r(   	get_arrayr'   r&   strnp)selfr(   r%   arrayr&    r/   7lib/python3.9/site-packages/xarray/backends/netCDF4_.py__init__3   s    
zBaseNetCDF4Array.__init__c                 C   sV   | j j: | jdd}|||< | j jr4| j jdd W d    n1 sH0    Y  d S )NF
needs_lock)r%   lockr*   	autocloseclose)r-   keyvaluedatar/   r/   r0   __setitem__B   s
    
zBaseNetCDF4Array.__setitem__Tc                 C   s   t dd S )NzVirtual Method)NotImplementedError)r-   r3   r/   r/   r0   r*   I   s    zBaseNetCDF4Array.get_arrayN)T)__name__
__module____qualname__	__slots__r1   r:   r*   r/   r/   r/   r0   r$   0   s   r$   c                   @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )NetCDF4ArrayWrapperr/   Tc                 C   sX   | j |}|j| j }|d tt |d W d    n1 sJ0    Y  |S )NF)r%   _acquire	variablesr(   Zset_auto_maskandscaler   AttributeErrorZset_auto_chartostring)r-   r3   dsvariabler/   r/   r0   r*   P   s    

(zNetCDF4ArrayWrapper.get_arrayc                 C   s   t || jt jj| jS N)r   Zexplicit_indexing_adapterr'   ZIndexingSupportZOUTER_getitem)r-   r7   r/   r/   r0   __getitem__Y   s    zNetCDF4ArrayWrapper.__getitem__c                 C   s   | j jrtjttd}ntj}zB| j j& | j	dd}|||}W d    n1 sT0    Y  W n t
y~   d}t
|Y n0 |S )N)ZcatchFr2   zThe indexing operation you are attempting to perform is not valid on netCDF4.Variable object. Try loading your data into memory first by calling .load().)r%   	is_remote	functoolspartialr   RuntimeErroroperatorgetitemr4   r*   
IndexError)r-   r7   rN   Zoriginal_arrayr.   msgr/   r/   r0   rG   ^   s    
,zNetCDF4ArrayWrapper._getitemN)T)r<   r=   r>   r?   r*   rH   rG   r/   r/   r/   r0   r@   M   s   
	r@   c                 C   s,   t jjddt j fD ]}|| } q| S )NT)Zallows_unicode)r   stringsZEncodedStringCoderZCharacterArrayCoderencode)varZcoderr/   r/   r0   _encode_nc4_variableu   s
    rT   c                 C   s   | t urtd| dd S )Nzunexpected dtype encoding zM. This shouldn't happen: please file a bug report at github.com/pydata/xarray)r+   AssertionError)r&   r/   r/   r0   $_check_encoding_dtype_is_vlen_string~   s    
rV   NETCDF4c                 C   s>   |dkrt | S d| jv r8| jd }t| |r8td| jS )NrW   r&   zLencoding dtype=str for vlen strings is only supported with format='NETCDF4'.)
_nc4_dtypeencodingrV   
ValueErrorr&   )rS   Z	nc_formatraise_on_invalid_encodingZencoded_dtyper/   r/   r0   _get_datatype   s    

r\   c                 C   s\   d| j v r | j d}t| n8tj| jr4t}n$| jjdv rH| j}nt	d| j |S )Nr&   )iufcSz(unsupported dtype for netCDF4 variable: )
rY   poprV   r   rQ   Zis_unicode_dtyper&   r+   kindrZ   )rS   r&   r/   r/   r0   rX      s    

rX   c                 C   s
   |  |S rF   )ZcreateGroup)Zdatasetnamer/   r/   r0   _netcdf4_create_group   s    re   c                 C   s   |dv r| S t |tstd|dd}|D ]\}z| j| } W q2 ty } z0|dkrh|| |} ntd| |W Y d }~q2d }~0 0 q2| S d S )N>   N /zgroup must be a string or Nonerg   rzgroup not found: )
isinstancer+   rZ   stripsplitgroupsKeyErrorOSError)rD   groupmodeZcreate_grouppathr7   er/   r/   r0   _nc4_require_group   s    
(rs   c                 C   s*   | j jdkr&d|v r&t|d |d< d S )Nra   
_FillValue)r&   rc   r,   Zstring_)r9   
attributesr/   r/   r0   _ensure_fill_value_valid   s    rv   c                 C   s`   | j jdvrB| j| j d}t| j|| j| j} | j	dd  | j
dddkr\td| S )N)r    r#   r    endianr   z]Attempt to write non-native endian type, this is not supported by the netCDF4 python library.)r&   	byteorderr9   ZastypeZnewbyteorderr   dimsattrsrY   rb   getr;   )rS   r9   r/   r/   r0   _force_native_endianness   s    r|   netCDF4c                    sZ   d u rd | j  }ddh}h d|r4d |rLd d |s|dd ur|d }t fd	d
t|| j| jD }	d|v }
|
o|d| jk}|	s|r|d= t fdd
| jD }|s|rd| v r|d= |D ]}||v r||= q|r6fdd|D }|rVt	d|d|dn t
|D ]}|vr>||= q>|S )Nr/   sourceoriginal_shape>   	complevelr&   rt   
chunksizes
contiguousshufflezlib
fletcher32least_significant_digitcompressionZcompression_optsr   c                 3   s$   | ]\}}}||ko| vV  qd S rF   r/   ).0r`   ddimunlimited_dimsr/   r0   	<genexpr>   s   z1_extract_nc4_variable_encoding.<locals>.<genexpr>c                 3   s   | ]}| v V  qd S rF   r/   )r   r   r   r/   r0   r         r   c                    s   g | ]}| vr|qS r/   r/   r   k)valid_encodingsr/   r0   
<listcomp>  r   z2_extract_nc4_variable_encoding.<locals>.<listcomp>z#unexpected encoding parameters for z
 backend: z. Valid encodings are: )rY   copyaddr{   anyzipr'   ry   keysrZ   list)rE   raise_on_invalidZlsd_okayZ	h5py_okayZbackendr   rY   Zsafe_to_dropr   Zchunks_too_bigZhas_original_shapeZchanged_shapeZvar_has_unlim_dimr   Zinvalidr/   )r   r   r0   _extract_nc4_variable_encoding   sL    






r   c                 C   s    t | }|jjdv o|jdkS )N)Ura   r   )r,   Zasarrayr&   rc   size)r8   Zarrr/   r/   r0   _is_list_of_strings  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 )*NetCDF4DataStorezStore for reading and writing data via the Python-NetCDF4 library.

    This store supports NetCDF3, NetCDF4 and OpenDAP datasets.
    )r5   formatrI   r4   	_filename_group_manager_modeNFc                 C   s   t |tjrD|d u r"t|\}}nt|tjur8td|}t|}|| _|| _|| _	| j
j| _| j
 | _t| j| _t|| _|| _d S )NzDmust supply a root netCDF4.Dataset if the group argument is provided)ri   r}   Datasetr   typerZ   r   r   r   r   rD   Z
data_modelr   filepathr   r	   rI   r   r4   r5   )r-   managerro   rp   r4   r5   rootr/   r/   r0   r1   4  s"    

zNetCDF4DataStore.__init__rh   rW   Tc                 C   s   t |tjrt|}t |ts(td|d u r4d}|d u r|dkrXt|rRt}qt}n,|d u sj|	drpt}nt}t
|t|g}t||||d}ttj|||d}| |||||
dS )NzJcan only read bytes or file-like objects with engine='scipy' or 'h5netcdf'rW   rh   )clobberdisklesspersistr   )rp   kwargs)ro   rp   r4   r5   )ri   osPathLikefspathr+   rZ   r	   r   NETCDF4_PYTHON_LOCK
startswithr   r   dictr   r}   r   )clsfilenamerp   r   ro   r   r   r   r4   Z
lock_makerr5   Z	base_lockr   r   r/   r/   r0   openM  s0    


zNetCDF4DataStore.openc                 C   s@   | j | }t|| j| j}W d    n1 s20    Y  |S rF   )r   Zacquire_contextrs   r   r   )r-   r3   r   rD   r/   r/   r0   rA   }  s    .zNetCDF4DataStore._acquirec                 C   s   |   S rF   )rA   r-   r/   r/   r0   rD     s    zNetCDF4DataStore.dsc           	         s    j }tt|| } fdd  D }t|| i }  }|d urT||   }|d ur|dkr~d|d< d |d< nd|d< t	||d< t
||d | j|d<  j|d	<  j|d
< t||||S )Nc                    s   i | ]}|  |qS r/   )	getncattrr   rS   r/   r0   
<dictcomp>  r   z8NetCDF4DataStore.open_store_variable.<locals>.<dictcomp>r   Tr   Fr   r~   r   r&   )
dimensionsr   ZLazilyIndexedArrayr@   ncattrsrv   filtersupdatechunkingtupler   r   r'   r&   r   )	r-   rd   rS   r   r9   ru   rY   r   r   r/   r   r0   open_store_variable  s(    





z$NetCDF4DataStore.open_store_variablec                    s   t  fdd jj D S )Nc                 3   s"   | ]\}}|  ||fV  qd S rF   )r   r   r   vr   r/   r0   r     s   z1NetCDF4DataStore.get_variables.<locals>.<genexpr>)r   rD   rB   itemsr   r/   r   r0   get_variables  s    
zNetCDF4DataStore.get_variablesc                    s   t  fdd j D S )Nc                 3   s   | ]}| j |fV  qd S rF   )rD   r   r   r   r/   r0   r     r   z-NetCDF4DataStore.get_attrs.<locals>.<genexpr>)r   rD   r   r   r/   r   r0   	get_attrs  s    zNetCDF4DataStore.get_attrsc                 C   s   t dd | jj D S )Nc                 s   s   | ]\}}|t |fV  qd S rF   )lenr   r/   r/   r0   r     r   z2NetCDF4DataStore.get_dimensions.<locals>.<genexpr>)r   rD   r   r   r   r/   r/   r0   get_dimensions  s    zNetCDF4DataStore.get_dimensionsc                 C   s   ddd | j j D iS )Nr   c                 S   s   h | ]\}}|  r|qS r/   )Zisunlimitedr   r/   r/   r0   	<setcomp>  s   z0NetCDF4DataStore.get_encoding.<locals>.<setcomp>)rD   r   r   r   r/   r/   r0   get_encoding  s    
zNetCDF4DataStore.get_encodingc                 C   s    |s|nd }| j j||d d S )N)r   )rD   ZcreateDimension)r-   rd   lengthZis_unlimitedZ
dim_lengthr/   r/   r0   set_dimension  s    zNetCDF4DataStore.set_dimensionc                 C   s<   | j dkrt|}t|r*| j|| n| j|| d S NrW   )r   r   r   rD   Zsetncattr_stringZ	setncattr)r-   r7   r8   r/   r/   r0   set_attribute  s
    
zNetCDF4DataStore.set_attributec                 C   s(   t |}| jdkrt|}nt|}|S r   )r|   r   rT   r   )r-   rE   r/   r/   r0   encode_variable  s
    

z NetCDF4DataStore.encode_variablec                 C   s   t || j|d}|j }|dd }|tu rF|d urFtd|dt|||d}|| jj	v rn| jj	| }	nZ| jj
|||j|dd|dd	|d
d|dd|dd|dd|d|d}	|	| t|| }
|
|jfS )N)r[   rt   znetCDF4 does not yet support setting a fill value for variable-length strings (https://github.com/Unidata/netcdf4-python/issues/730). Either remove '_FillValue' from encoding on variable zH or set {'dtype': 'S1'} in encoding to use the fixed width NC_CHAR type.)r   r   r   Fr      r   Tr   r   r   r   r   )Zvarnamedatatyper   r   r   r   r   r   r   rw   r   
fill_value)r\   r   rz   r   rb   r+   r;   r   rD   rB   ZcreateVariablery   r{   Z	setncattsr@   r9   )r-   rd   rE   Zcheck_encodingr   r   rz   r   rY   Znc4_vartargetr/   r/   r0   prepare_variable  sB    
	






z!NetCDF4DataStore.prepare_variablec                 C   s   | j   d S rF   )rD   syncr   r/   r/   r0   r     s    zNetCDF4DataStore.syncc                 K   s   | j jf i | d S rF   )r   r6   )r-   r   r/   r/   r0   r6     s    zNetCDF4DataStore.close)	rh   rW   NTFFNNF)T)F)FN)r<   r=   r>   __doc__r?   r   r1   classmethodr   rA   propertyrD   r   r   r   r   r   r   r   r   r   r   r6   r/   r/   r/   r0   r   #  s<   
         /


		 
0r   c                   @   s"   e Zd ZeZdd Zd
dd	ZdS )NetCDF4BackendEntrypointc                 C   sb   t |trt|rdS t|}|d ur0|dS ztj|\}}W n tyX   Y dS 0 |dv S )NT)s   CDFs   HDF

F>   z.nc4z.cdfz.nc)	ri   r+   r	   r
   r   r   rq   splitext	TypeError)r-   filename_or_objZmagic_number_extr/   r/   r0   guess_can_open  s    
z'NetCDF4BackendEntrypoint.guess_can_openTNrh   rW   Fc                 C   sp   t |}tj||
||	|||||d	}t }t|* |j||||||||d}W d    n1 sb0    Y  |S )N)rp   r   ro   r   r   r   r4   r5   )mask_and_scaledecode_timesconcat_charactersdecode_coordsdrop_variables
use_cftimedecode_timedelta)r   r   r   r   r   open_dataset)r-   r   r   r   r   r   r   r   r   ro   rp   r   r   r   r   r4   r5   storeZstore_entrypointrD   r/   r/   r0   r     s2    
$
z%NetCDF4BackendEntrypoint.open_dataset)TTTTNNNNrh   rW   TFFNF)r<   r=   r>   has_netcdf4Z	availabler   r   r/   r/   r/   r0   r     s$                  r   Znetcdf4)rW   F)FTFr}   N)=rJ   rM   r   
contextlibr   Znumpyr,   rf   r   Zcoding.variablesr   corer   Z
core.utilsr   r   r	   r
   Zcore.variabler   commonr   r   r   r   r   r   r   Zfile_managerr   r   locksr   r   r   r   r   Znetcdf3r   r   r   r   r}   r   ModuleNotFoundErrorZ_endian_lookupr   r$   r@   rT   rV   r\   rX   re   rs   rv   r|   r   r   r   r   r/   r/   r/   r0   <module>   sT   $	
(	
     
E _@