B
    Qav                 @   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|\}
}x|dkrtj|
\}
}q~W |s|
}| }tjtj|}tj|st| |d| |d	kr|rhtj|d
 d	krh|dkrt|}t|d t|d ft|d  fdd D }W d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v}xP  D ]D} | }	|dj||t|	j	t|	j|d |j ||	d|d}qW t!|dkrt|d\xT|D ]L}| }|dj||t|j	t|j|d |j ||dd d|d qpW W dQ R X xJ| D ]>\}}yt||j"|< W n    t|#d|j"|< Y nX qW |dk	rlxJ| D ]>\}}|dk	r*||| j"d< |d |d!| d"|  q*W W dQ R X |d#| nJt  }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rR|d |d g}n|d/kr|d(|d'< d&|d%< |%d0d1d2krR|d |d g}n|d3krd)|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rR|d t'd<|d
   |d< n|d=krRd*|d'< d>d*d)d(d?d@d;dAg}|d' |krdB||d' }|dC|7 }t|t(|||d' |d% dD |dE| t)||dF |dG |S )Ha$   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   L/home/centos/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: {}z create HDF5 file: {} with w modec             S   s   g | ]}t |qS r   )len)r	   r   r   r   r   r   d   s    wzKcreate 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UNITzadd /<z attribute: UNIT = zfinished writing to {}BANDS
INTERLEAVEBIL	DATA_TYPEfloat32int16int8)floatshortbyte)z.unw	magnitudephase)z.corz.hgt	PROCESSORisceroipacz.dem)z.trans)z.utm_to_rdc   BIP)z.mliz.fltz.slcz.int	complex64y              ?z.mskboolfloat64	complex32
complex128z0Un-supported file type "{}" with data type "{}"!z
Supported data type list: {})	data_type
interleavez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_filer)   ds_unit_dictrD   vprintmetar'   fbasefextout_dirZ
auxDsNamesdsNamesmaxDigitfdsNamedsr
   r   Zkey_list	data_listZDATA_TYPE_DICTZ
data_typesmsgr   )r   r   r   r   write   s    




&





 

,












 
rx   c          
   C   s  |rt ndd }|d |r0dd | D }nH|rpt|d}	dd |	j D }W d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}x|	 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 W dQ R X n4t|}|d }x |D ]}|t|dg||< qW tjtj| }tj|st| |d| t| d~}|d|  tdd | D }x| D ]}|| d }|| d }|}|dkrtd}t|dkrd|d |d f}n|}|dj||t|t||d |j||||d|d }t|| dkrF|| d dk	rFt|| d |dd< qFW x$| D ]\}}t||j|< qW |dk	rxJ| D ]>\}}|dk	rN||| jd!< |d"|d#| d$|  qNW W dQ R X |d%|  | S )&a8  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/3D 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 )Nr   )r   r   r   r   r   r     r   zlayout_hdf5.<locals>.<lambda>z2--------------------------------------------------c             S   s   i | ]\}}||qS r   r   )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   r   r     s    Nzgrab metadata from ref_file: {}zNo metadata or ref_file found.z"No ds_name_dict or ref_file found!z(grab dataset structure from ref_file: {}r   r   r   )z.h5z.he5r   r/   zcrerate directory: {}r"   z create HDF5 file: {} with w modec             S   s   g | ]}t |qS r   )r!   )r	   r   r   r   r   r   O  s    zlayout_hdf5.<locals>.<listcomp>r   )connectComponentlzf   r;   zOcreate dataset  : {d:<{w}} of {t:<25} in size of {s:<20} with compression = {c})r#   r"   r$   r%   r&   T)r   maxshaperL   r(   r)   r*   zadd /r+   z attribute: UNIT = zclose  HDF5 file: {}) rE   rF   r   rY   r`   rV   rH   rN   rO   r[   FileNotFoundErrorrP   rX   r   r   r   r   rL   r   tupler   get_slice_listrR   rS   rT   rU   r]   r!   r^   r_   rI   rK   )fnameZds_name_dictri   rk   rj   r)   rD   rl   rm   r   ro   r   Zshape2d_origr
   ru   Zds_shapeZds_namesZds_dtypeds_namefdirrs   Z	max_digitrB   Z
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}nJt|dkr`d|d d|d g}n(t|dkrd|d d|d d|d g}|rtd td| | td|| t| |}t|d	kr||| |d |d |d |d |d
 |d f< n^t|d
kr@||| |d |d |d |d f< n&t|dkrf||| |d |d < W dQ R X |rtd|  | S )a  Write data to existing HDF5 dataset in disk block by block.
    Parameters: data        - np.ndarray 1/2/3D matrix
                datasetName - str, dataset name
                block       - list of 2/4/6 int, for
                              [zStart, zEnd,
                               yStart, yEnd,
                               xStart, xEnd]
                mode        - str, open mode
    Returns:    fname
    Nr   r   r;   r{   z2--------------------------------------------------zopen  HDF5 file {} in {} modez!writing dataset /{:<25} block: {}         zclose HDF5 file {}.)r   r   r!   r   rE   rV   r   rY   )r   r'   datasetNameblockmoderD   r   rs   r   r   r   write_hdf5_block  s6    
8*"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 }xj fdd
| D D ]P}|| }	|r
tdj||t|	jt|	j|d |j||	dd d|d qW x&|j D ]\}
}t||j|
< q4W |  |  |rt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 modez create HDF5 file: {} with w moder   r"   Nc             S   s   g | ]}t |qS r   )r!   )r	   r   r   r   r   r     s    z'remove_hdf5_dataset.<locals>.<listcomp>c                s   g | ]}| kr|qS r   r   )r	   r   )datasetNamesr   r   r     s    zKcreate dataset /{d:<{w}} of {t:<10} in size of {s:<20} with compression={c})r#   r"   r$   r%   r&   T)r'   r(   r)   zfinished writing to {}z:old file is now saved as: {}. Use rm command to delete it.)r   r^   r   rE   rV   rN   rO   joinrR   basenameshutilmover   rY   r]   r   rL   r   r_   r`   rF   close)r   r   rD   Z	temp_filefifor)   rr   rt   ru   r
   r   r   )r   r   remove_hdf5_dataset  s8    	
$r   Fc       	   
   C   s>  d}|rBt  }tj|r$t|}t|  t| rBd}|r:d| 	 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@}x8t| 	 D ](}|djt
||t
| | d qW W d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_FIRSTzwrite file: {}c             S   s   g | ]}t |qS r   )r!   )r	   r
   r   r   r   r     s    z$write_roipac_rsc.<locals>.<listcomp>r;   r"   z{k:<{d}}    {v}
)kr#   vN)rM   rN   rO   r[   r   read_roipac_rscsetrF   issubsetr   r^   r3   rE   rV   r]   opensortedrx   )	ri   rh   Zupdate_moderD   runZrsc_dictrr   rs   r
   r   r   r   rg     s0    
"rg   c          	   C   sX  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}xNt|D ]B}dj|| d  |d tj|dd |
| ||	d}||7 }qW |d7 }t|d}|| W d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)r2   r1   r0   r?   r=   rA   248Z16Z32r/   r   r   r,   r-   r<   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#   brs   ioZpoloz</VRTDataset>
r"   )	rX   rH   rV   rangerN   rO   r   r   rx   )rm   rh   Z
dtype_dictZpixel_offset_dictZpixel_offsetlengthwidthnum_bandrC   line_offsetZimage_offsetZds_strbandZband_strrs   r   r   r   write_gdal_vrt  sP    

r   c       	      C   s  ddl }ddl}tj| d  }tj| }| d }|s@|j }nF|dkrT|j }n2|dkrh|j }n|dkr||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   z.slcz.unwz.intr   r   ZREADr,   1r-   r.   zwrite file: z.xmlz.vrt)r9   isceobjr   NUMPY2GDAL_DATATYPEGDAL2ISCE_DATATYPEZImageZcreateImageZcreateSlcImageZcreateUnwImageZcreateIntImageZsetFilenameZsetWidthrX   Z	setLengthZsetAccessModerc   bandsdataTypeschemeZ	renderHdrZ	renderVRTrE   )	rm   r   rD   r9   r   Z
dtype_gdalZ
dtype_isceZ
image_typeimgr   r   r   write_isce_xml`  s6    	
    


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   z.unwr   r;   r,   r0   r/   r.   r-   r   Zisce_intz.intr   r=   Zisce_corz.corZisce_slcz.slcr<   z un-recognized ISCE file type: {})replacetofiler   rX   rH   rV   r   )r'   rh   Z	file_typer   r   rm   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 }x"| dd	 D ]}t||f}qxW || |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 ))rL   )rI   rK   )r	   x)rB   r   r   r     s    z write_binary.<locals>.<listcomp>r<   c             S   s   g | ]}| d dqS )r   )reshape)r	   r   r   r   r   r     s    r   c             S   s   g | ]}| d dqS )r   r   )r   )r	   r   r   r   r   r     s    r   N)rQ   rL   rd   rI   hstackr   )rv   rh   rB   rC   r'   Zdatair   )rB   r   rf     s    	
rf   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)
    r;   r   r   r{   z0Error while getting args: support 2/3 args only.N)rL   )r!   rE   rI   r   flattenrK   r0   r   )r   amppharh   r'   r   r   r   write_float32  s    	


r   c             C   s   t j| t jd} | | |S )z$write complex float32 data into file)rL   )rI   rK   r=   r   )r'   rh   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   r;   r   )sizer   r   rI   zerosr1   r   rK   realimagr   )r'   rh   	num_pixelZid1Z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.)rL   )rI   rK   r?   r   )r'   rh   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.)rL   )rI   rK   r0   r   )r'   rh   r   r   r   write_real_float32*  s    
r   c             C   s   t j| t jd} | | |S )N)rL   )rI   rK   r1   r   )r'   rh   r   r   r   write_real_int161  s    
r   c             C   s   t j| t jd} | | |S )N)rL   )rI   rK   r5   r   )r'   rh   r   r   r   
write_byte7  s    
r   c             C   s   t j| t jd} | | |S )N)rL   )rI   rK   bool_r   )r'   rh   r   r   r   
write_bool=  s    
r   )NNNNT)NNNNNT)Nr   T)T)FF)T)r   )Nr.   )rN   r   r   numpyrI   mintpy.utilsr   rx   r   r   r   rg   r   r   r   rf   r   r   r   r   r   r   r   r   r   r   r   r   <module>
   s.   
 Q
 !
8
1
-I
(
9
#