U
    ]blx                     @   s   d dl Z d dlZd dlZd dlZd dlmZ d*ddZd+ddZd,d	d
Z	d-ddZ
d.ddZdd Zd/ddZd0ddZd1ddZdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) ZdS )2    N)readfileTc                    s  |rt ndd }|r(dd | D }n|r8t|}ntdt tjrlt  j	}	t
  |	 |d < tj|\}
}|dkrtj|
\}
}q||s|
}| }tjtj|}tj|st| |d| |d	krt|rdtj|d
 d	krd|dkrt|}t|d t|d ft|d  fdd D }W 5 Q R X ng }t  | }|d dkrd|krtd|d tj|rt| |d| t d| tdd |D }t|df}  D ]D} | }	|dj||t|	j	t|	j|d |j ||	d|d}q t!|dkrt|dX|D ]L}| }|dj||t|j	t|j|d |j ||dd d|d qfW 5 Q R X | D ]>\}}zt||j"|< W n    t|#d|j"|< Y nX q|dk	rX| D ]>\}}|dk	r||| j"d< |d |d!| d"|  qW 5 Q R X |d#| nLt  }t $ }t!||d$< |%d%d&& |d%< |%d'd( |d'< d(d)d*d+}|d' | kr||d'  |d'< |d,kr*d(|d'< d&|d%< |d-d.gkr>|d |d g}n|d/krhd(|d'< d&|d%< |%d0d1d2kr>|d |d g}n|d3kr|d)|d'< n|d4krd(|d'< d&|d%< n|d5krd6|d$< d(|d'< d7|d%< n|d8krd(|d'< nn|d9krd
|d$< nZ|d:kr,d
|d$< d;|d'< |d-d.gkr>|d t'd<|d
   |d< n|d=kr>d*|d'< d>d*d?d)d(d@dAd;dBg	}|d' |krdC||d' }|dD|7 }t|t(|||d' |d% dE |dF| t)||dG |dH |S )Ia$   Write one file.
    Parameters: datasetDict  - dict of dataset, with key = datasetName and value = 2D/3D array, e.g.:
                    {'height'        : np.ones((   200,300), dtype=np.int16),
                     'incidenceAngle': np.ones((   200,300), dtype=np.float32),
                     'bperp'         : np.ones((80,200,300), dtype=np.float32),
                     ...}
                out_file     - str, output file name
                metadata     - dict of attributes
                ref_file     - str, reference file to get auxliary info
                compression  - str, compression while writing to HDF5 file, None, "lzf", "gzip"
                ds_unit_dict - dict, dataset unit definition
                    {dname : dunit,
                     dname : dunit,
                     ...
                    }
    Returns:    out_file     - strs
    Examples:   dsDict = dict()
                dsDict['velocity'] = np.ones((200,300), dtype=np.float32)
                write(datasetDict=dsDict, out_file='velocity.h5', metadata=atr)
    c                  _   s   d S N argskwargsr   r   M/home/exouser/operations/rsmas_insar/sources/MintPy/mintpy/utils/writefile.py<lambda>&       zwrite.<locals>.<lambda>c                 S   s   i | ]\}}||qS r   r   .0keyvaluer   r   r   
<dictcomp>*   s      zwrite.<locals>.<dictcomp>z$No metadata or reference file input.	FILE_TYPE)z.geoz.rdrz.fullz.wgs84zcreate directory: {}z.h5z.he5   NLENGTHWIDTHrc                    sF   g | ]>}|t   krt| tjr| jd d kr|qS )N)listkeys
isinstanceh5pyDatasetshaper   idatasetDictfrshape2dr   r   
<listcomp>P   s
    zwrite.<locals>.<listcomp>)
timeseriesifgramStackdatez-Can not write {} file without 'date' dataset!zdelete exsited file: {} create HDF5 file: {} with w modec                 S   s   g | ]}t |qS r   lenr   r   r   r   r#   d   s     wKcreate dataset /{d:<{w}} of {t:<10} in size of {s:<20} with compression={c}dr*   tscTdatachunkscompressionr   zKcreate dataset /{d:<{w}} of {t:<10} in size of {s:<10} with compression={c}zutf-8UNITadd /< attribute: UNIT = finished writing to {}BANDS
INTERLEAVEBIL	DATA_TYPEfloat32int16int8)floatshortbyte).unw	magnitudephase).corz.hgt	PROCESSORisceroipacz.dem)z.trans)z.utm_to_rdc   BIP)z.mliz.flt.slc.int	complex64y              ?z.mskbooluint8float64	complex32
complex128z0Un-supported file type "{}" with data type "{}"!z
Supported data type list: {})	data_type
interleavewrite file: {}z.rsc)	print_msg)*printitemsr   read_attribute
ValueErrorr   npndarrayarraydtypedictospathsplitextlowerdirnameabspathisdirmakedirsformatget_hdf5_compressionintr   Filer   r   	Exceptionisfileremovemaxstrr   create_datasetr)   attrsencodevaluesgetupperexpwrite_binarywrite_roipac_rsc)r    out_filemetadataref_filer4   ds_unit_dictrX   vprintmetar2   fbasefextZout_dirZ
auxDsNamesdsNamesmaxDigitfdsNamedsr   r   Zkey_list	data_listZDATA_TYPE_DICT
data_typesmsgr   r   r   write   s   



&





*












 
r   c              
   C   s  |rt ndd }|d |r0dd | D }nH|rpt|d}	dd |	j D }W 5 Q R X |d| ntd	|d
kr|rtj	|st
dn|d| i }tj|d }
t|d t|d f}|
dkrt|d}	t|	jd t|	jd f}|	 D ]v}|	| }t|tjr|jdd
 |kr\|j|j|d
d
 g||< n*t|j}||dd
< |jt|d
g||< qW 5 Q R X n0t|}|d }|D ]}|t|d
g||< qtjtj| }tj|s t| |d| t| dr}|d|  tdd | D }| D ]}|| d }|| d }|}|dkrjd}t|dkrd
|d |d f}n|}|dj||t|t||d |j||||d|d }t|| dkr<|| d d
k	r<t|| d |d
d
< q<| D ]\}}t||j|< q|d
k	r|| D ]>\}}|d
k	r<||| jd!< |d"|d#| d$|  q<W 5 Q R X |d%|  | S )&a:  Create HDF5 file with defined metadata and (empty) dataset structure

    Parameters: fname        - str, HDF5 file path
                ds_name_dict - dict, dataset structure definition
                               {dname : [dtype, dshape],
                                dname : [dtype, dshape, None],
                                dname : [dtype, dshape, 1/2/3/4D np.ndarray], #for aux data
                                ...
                               }
                metadata     - dict, metadata
                ds_unit_dict - dict, dataset unit definition
                               {dname : dunit,
                                dname : dunit,
                                ...
                               }
                ref_file     - str, reference file for the data structure
                compression  - str, HDF5 compression type
    Returns:    fname        - str, HDF5 file path

    Example:    layout_hdf5('timeseries_ERA5.h5', ref_file='timeseries.h5')
                layout_hdf5('timeseries_ERA5.5h', ds_name_dict, metadata)

    # structure for ifgramStack
    ds_name_dict = {
        "date"             : [np.dtype('S8'), (num_ifgram, 2)],
        "dropIfgram"       : [np.bool_,       (num_ifgram,)],
        "bperp"            : [np.float32,     (num_ifgram,)],
        "unwrapPhase"      : [np.float32,     (num_ifgram, length, width)],
        "coherence"        : [np.float32,     (num_ifgram, length, width)],
        "connectComponent" : [np.int16,       (num_ifgram, length, width)],
    }

    # structure for geometry
    ds_name_dict = {
        "height"             : [np.float32, (length, width), None],
        "incidenceAngle"     : [np.float32, (length, width), None],
        "slantRangeDistance" : [np.float32, (length, width), None],
    }

    # structure for timeseries
    dates = np.array(date_list, np.string_)
    ds_name_dict = {
        "date"       : [np.dtype("S8"), (num_date,), dates],
        "bperp"      : [np.float32,     (num_date,), pbase],
        "timeseries" : [np.float32,     (num_date, length, width)],
    }
    c                  _   s   d S r   r   r   r   r   r   r	     r
   zlayout_hdf5.<locals>.<lambda>2--------------------------------------------------c                 S   s   i | ]\}}||qS r   r   r   r   r   r   r     s      zlayout_hdf5.<locals>.<dictcomp>r   c                 S   s   i | ]\}}||qS r   r   r   r   r   r   r     s      zgrab metadata from ref_file: {}zNo metadata or ref_file found.Nz"No ds_name_dict or ref_file found!z(grab dataset structure from ref_file: {}r   r   r   r   r   r=   zcrerate directory: {}r*   r'   c                 S   s   g | ]}t |qS r   r(   r   r   r   r   r#   O  s     zlayout_hdf5.<locals>.<listcomp>r   )connectComponentlzf   rK   zOcreate dataset  : {d:<{w}} of {t:<25} in size of {s:<20} with compression = {c}r,   T)r   maxshaper`   r3   r4   r5   r6   r7   r8   zclose  HDF5 file: {}) rY   rZ   r   rm   rt   rj   r\   rb   rc   ro   FileNotFoundErrorrd   rl   r   r   r   r   r`   r   tupler   get_slice_listrf   rg   rh   ri   rq   r)   rr   rs   r]   r_   )fnameZds_name_dictr}   r   r~   r4   rX   r   r   r!   r   r"   Zshape2d_origr   r   Zds_shapeZds_namesZds_dtypeds_namefdirr   	max_digitrU   
data_shapeZds_compZ	max_shaper   r   r   r   layout_hdf5   s    0



$


$

*r   ac              	   C   s  |dkrt |trt|f}n|j}t|dkr>d|d g}n|t|dkr`d|d d|d g}nZt|dkrd|d d|d d|d g}n0t|dkrd|d d|d d|d d|d g}|rtd td| | td	|| t| |}t|d
krH||| |d |d |d |d |d |d |d |d f< nt|dkr||| |d |d |d |d |d |d f< n^t|dkr||| |d |d |d |d f< n&t|dkr||| |d |d < W 5 Q R X |r
td|  | S )a  Write data to existing HDF5 dataset in disk block by block.
    Parameters: data        - np.ndarray 1/2/3/4D matrix
                datasetName - str, dataset name
                block       - list of 2/4/6/8 int, for
                              [d1Start, d1End,
                               d2Start, d2End,
                               yStart, yEnd,
                               xStart, xEnd]
                mode        - str, open mode
    Returns:    fname
    Nr   r   rK   r      r   zopen  HDF5 file {} in {} modez!writing dataset /{:<25} block: {}            zclose HDF5 file {}.)r   r   r)   r   rY   rj   r   rm   )r   r2   datasetNameblockmoderX   r   r   r   r   r   write_hdf5_block  s    
            "r   c              	      s~  t  trt  |r&td |  tjtj| dtj	| }td| | t
| | |rtd| td|  t|d}t| d}d}td	d
 t| D } fdd
| D D ]P}|| }	|rtdj||t|	jt|	j|d |j||	dd d|d q|j D ]\}
}t||j|
< q.|  |  |rztd|  td| | S )a  Remove an existing dataset from an HDF5 file.
    Parameters: fname : str, HDF5 file name/path
                datasetName : (list of) str, dataset name(s)
    Returns:    fname : str,
    Example:    remove_hdf5_dataset('./inputs/ifgramStack.h5', 'unwrapPhase_phaseClosure')
                remove_hdf5_dataset('./inputs/ifgramStack.h5', ['unwrapPhase_phaseClosure',
                                                                'unwrapPhase_bridging'])
    zdelete {} from file {}ztmp_{}zmove {} to {}z read   HDF5 file: {} with r moder'   r   r*   Nc                 S   s   g | ]}t |qS r   r(   r   r   r   r   r#     s     z'remove_hdf5_dataset.<locals>.<listcomp>c                    s   g | ]}| kr|qS r   r   r   datasetNamesr   r   r#     s      r+   r,   Tr1   r9   z:old file is now saved as: {}. Use rm command to delete it.)r   rr   r   rY   rj   rb   rc   joinrf   basenameshutilmover   rm   rq   r   r`   r   rs   rt   rZ   close)r   r   rX   	temp_filefifor4   r   r   r   r   r   r   r   r   remove_hdf5_dataset  sB    	
$    r   Fc           	   
   C   s:  d}|rBt  }tj|r$t|}t|  t| rBd}|r6d| 	 kr`| d | d< d| 	 krt
t| d | d< t
t| d | d< t
t| d | d< t
t| d | d< |rtd	| td
d | 	 D dg }t|d<}t| 	 D ](}|djt
||t
| | d qW 5 Q R X |S )a  Write attribute dict into ROI_PAC .rsc file
    Inputs:
        metadata : dict, attributes dictionary
        out_file : rsc file name, to which attribute is writen
        update_mode : bool, skip writing if
                      1) output file existed AND
                      2) no new metadata key/value
        print_msg   : bool, print message
    Output:
        out_file
    TFr   FILE_LENGTHX_STEPY_STEPX_FIRSTY_FIRSTrW   c                 S   s   g | ]}t |qS r   r(   )r   r   r   r   r   r#     s     z$write_roipac_rsc.<locals>.<listcomp>rK   r*   z{k:<{d}}    {v}
)kr-   v)ra   rb   rc   ro   r   read_roipac_rscsetrZ   issubsetr   rr   rA   rY   rj   rq   opensortedr   )	r}   r|   Zupdate_moderX   runZrsc_dictr   r   r   r   r   r   r{     s2    

r{   c              	   C   sT  ddddddd}dd	d
dddd}t || d  }t | d t | d  }}t | d }| d }|dkr||| | }	|}
nJ|dkr|| | }	|| }
n,|dkr|| }	|| | }
ntd|dj| d | d d}t|D ]B}dj|| d  |d tj|dd |
| ||	d}||7 }q|d7 }t|d}|| W 5 Q R X |S )a  Write GDAL VRT file.

    !!! This function is NOT RIGHT. DO NOT USE IT. Keep here as a placeholder ONLY. !!!
    It needs more work.

    Parameters: meta     - dict, dictionary of metadata
                out_file - str, VRT file name to which attributes are written
    ZByteZInt16ZFloat32ZFloat64ZCFloat32ZCFloat64)r@   r?   r>   rR   rO   rT   248Z16Z32r=   r   r   r:   r;   rL   r<   BSQz&un-recognized band interleave type: {}z1<VRTDataset rasterXSize="{w}" rasterYSize="{l}">
)r*   la;  <VRTRasterBand dataType="{d}" band="{b}" subClass="VRTRawRasterBand">
        <SourceFilename relativeToVRT="1">{f}</SourceFilename>
        <ByteOrder>LSB</ByteOrder>
        <ImageOffset>{io}</ImageOffset>
        <PixelOffset>{po}</PixelOffset>
        <LineOffset>{lo}</LineOffset>
    </VRTRasterBand>
        r   N)r-   br   ioZpoloz</VRTDataset>
r*   )	rl   r\   rj   rangerb   rc   r   r   r   )r   r|   Z
dtype_dictZpixel_offset_dictZpixel_offsetlengthwidthnum_bandrV   line_offsetZimage_offsetZds_strbandZband_strr   r   r   r   write_gdal_vrt#  sV    


r   c                 C   s  ddl }ddl}tj| d  }| d }|s6|j }nF|dkrJ|j }n2|dkr^|j }n|dkrr|j }n
|j }|	| |
t| d  |t| d	  |d
 t| dd|_||_| dd|_|  |  |rtd| d td| d dS )a  Write XML metadata file in ISCE-2 format

    Parameters: meta      - dict, attributes dictionary
                fname     - str, path of data file, not the metadata file
                print_msg - bool, print out message
    Examples:   write_isce_xml(atr, fname='filt_fine.cor')
    r   Nr=   r   rM   rD   rN   r   r   READr:   1r;   r<   zwrite file: z.xmlz.vrt)rI   isceobjr   DATA_TYPE_NUMPY2ISCEImageZcreateImageZcreateSlcImageZcreateUnwImageZcreateIntImageZsetFilenameZsetWidthrl   Z	setLengthZsetAccessModerw   bandsdataTypeschemeZ	renderHdrZ	renderVRTrY   )r   r   rX   rI   r   r`   Z
image_typeimgr   r   r   write_isce_xmll  s4    	    


r   isce_unwc                 C   s   | dd}| | | j\}}||d}|dkrdd|d< d|d< d	|d
< d|d< t|d |d< n|dkrd|d< d|d< d|d
< d|d< nb|dkrd|d< d|d< d	|d
< d|d< n8|dkrd|d< d|d< d|d
< d|d< ntd|t|| |S )a  write data to file in ISCE format

    Parameters: data      - 2D np.ndarray, binary data matrix
                out_file  - str, path of output binary data file
                file_type - str, file type
    Returns:    out_file  - str, path of output binary data file
    -_)r   r   r   rD   r   rK   r:   r>   r=   r<   r;   r   Zisce_intrN   r   rO   Zisce_corrG   Zisce_slcrM   rL   z un-recognized ISCE file type: {})replacetofiler   rl   r\   rj   r   )r2   r|   Z	file_typer   r   r   r   r   r   write_isce_file  s<    	





r   r<   c                    s    r,     | d jkr, fdd| D } | }|dkrLdd | D } n|dkrbdd | D } | d }| dd	 D ]}t||f}qv|| |S )
a]  Write binary file.
    Parameters: data_list  - list of 2D np.ndarray matrices
                out_file   - str, path of the output binary file
                data_type  - str/np.dtype, numpy data type object
                interleave - str, band interleave type, BSQ, BIL, BIP
    Returns:    out_file   - str, path of the output binary file
    r   c                    s   g | ]}t j| d qS )r`   )r]   r_   r   xrU   r   r   r#     s     z write_binary.<locals>.<listcomp>rL   c                 S   s   g | ]}| d dqS )r   reshaper   r   r   r   r#     s     r   c                 S   s   g | ]}| d dqS )r   r   r   r   r   r   r   r#     s     r   N)re   r`   rx   r]   hstackr   )r   r|   rU   rV   r2   Zdatair   r   r   rz     s    	
rz   c                  G   s   t | dkr&| d }| d }| d }n2t | dkrL| d }| d }| d }ntd dS t||f }tj|tjd}|| |S )a  Write ROI_PAC rmg format with float32 precision (BIL)
    Format of the binary file is same as roi_pac unw, cor, or hgt data.
          should rename to write_rmg_float32()

    Exmaple:
            write_float32(phase, out_file)
            write_float32(amp, phase, out_file)
    rK   r   r   r   z0Error while getting args: support 2/3 args only.Nr   )r)   rY   r]   r   flattenr_   r>   r   )r   ampphar|   r2   r   r   r   write_float32  s    	


r   c                 C   s   t j| t jd} | | |S )z$write complex float32 data into filer   )r]   r_   rO   r   r2   r|   r   r   r   write_complex_float32
  s    
r   c                 C   s   | j }ttdd| d}ttdd| d}td| dgtj}tt| jtj|df||< tt| j	tj|df||< |
| |S )zWrite gamma scomplex data, i.e. .slc file.
        data is complex 2-D matrix
        real, imagery, real, ...
    Write in this way, because numpy does not have complex int16 directly.
    r   rK   r   )sizer   r   r]   zerosr?   r   r_   realimagr   )r2   r|   	num_pixelid1id2Fr   r   r   write_complex_int16  s      
r   c                 C   s   t j| t jd} | | |S )z)write isce float data, i.e. hgt.rdr file.r   )r]   r_   rR   r   r   r   r   r   write_real_float64.  s    
r   c                 C   s   t j| t jd} | | |S )z'write gamma float data, i.e. .mli file.r   )r]   r_   r>   r   r   r   r   r   write_real_float325  s    
r   c                 C   s   t j| t jd} | | |S Nr   )r]   r_   r?   r   r   r   r   r   write_real_int16<  s    
r   c                 C   s   t j| t jd} | | |S r   )r]   r_   rC   r   r   r   r   r   
write_byteB  s    
r   c                 C   s   t j| t jd} | | |S r   )r]   r_   bool_r   r   r   r   r   
write_boolH  s    
r   )NNNNT)NNNNNT)Nr   T)T)FF)T)r   )Nr<   )rb   r   r   numpyr]   mintpy.utilsr   r   r   r   r   r{   r   r   r   rz   r   r   r   r   r   r   r   r   r   r   r   r   <module>
   s.   
 Q
 !
D
1
-I
'
9
#