U
     xb                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	m
Z
mZmZmZ d dlmZmZmZ d dlT d.ddZd/d	d
Zd0ddZd1ddZd2ddZd3ddZd4ddZd5ddZd6ddZd7dd Ze dfd!d"Zd8d#d$Zd9d%d&Z d:d'd(Z!d;d*d+Z"d<d,d-Z#dS )=    N)derampifgramStack
timeseriesgeometryDatasetNames)ptimereadfile	writefile)*c                 C   s   t | }|dkr.ddt|d t|d f}t|d |d  d }t|d |d  d }d| krt|d }t|d	 }t|d
 }t|d }|||  }	|||  }
nD|||d |d f}tt j| d|dd }	tt j| d|dd }
|	|
fS )z#Get the lat/lon of the scene centerNr   WIDTHLENGTH         Y_FIRSTX_FIRSTY_STEPX_STEPlatitudedatasetNamebox	longitude)r   read_attributeintkeysfloatread)	geom_filer   metaZcol_cZrow_clat0lon0lat_steplon_steplat_cZlon_cZbox_c r$   J/home/exouser/operations/rsmas_insar/sources/MintPy/mintpy/utils/utils1.pyget_center_lat_lon   s     
r&   maskTempCoh.h5	quadraticc           	      C   s  |dkrt d | }ndtj| d }tj|d d }t|||gdddkrt|| d	dkrtj| sd
|  }|d7 }t|nt| |||d}t d|  t	|j
||d}t d|  tj|tdt}|dddf tj }t|dddf }|||fS )aY  Calculate deramped standard deviation in space for each epoch of input timeseries file.
    Parameters: timeseries_resid_file - string, timeseries HDF5 file,
                    e.g. timeseries_ERA5_demErrInvResid.h5
                mask_file - string, mask file, e.g. maskTempCoh.h5
                ramp_type - string, ramp type, e.g. linear, quadratic, no for do not remove ramp
    Returns:    std_list  - list of float, standard deviation of deramped input timeseries file
                date_list - list of string in YYYYMMDD format, corresponding dates
                std_file  - string, text file with std and date info.
    Example:    import mintpy.utils.utils as ut
                std_list, date_list = ut.get_residual_std('timeseries_ERA5_demErrInvResid.h5',
                                                          'maskTempCoh.h5')[:2]
    noNo ramp removal
{}_ramp.h5r   z_std.txtFout_filein_filecheck_readablerunr-   r.   -Can not find input timeseries residual file: $
Re-run dem_error.py to generate it.	ramp_type	mask_filer-   zBcalculating residual standard deviation for each epoch from file: maskFileoutFilezread timeseries RMS from file: dtypeNr   )printformatospathsplitextrun_or_skipisfile	Exception
run_derampr   timeseries_stdnploadtxtbytesastypestrfloat32tolistlist)	timeseries_resid_filer6   r5   deramped_fileZstd_filemsgfcZstd_list	date_listr$   r$   r%   get_residual_std0   s.    
rS   c           	      C   s0  |dkrt d | }ndtj| d }tjtjtj|dtj|d }t|||gdddkrt|| d	dkrtj	| sd
|  }|d7 }t
|nt| |||d}t d|  t|j||d}t d|  tj|tdt}|dddf tj }t|dddf }|||fS )aV  Calculate deramped Root Mean Square in space for each epoch of input timeseries file.
    Parameters: timeseries_resid_file : string,
                    timeseries HDF5 file, e.g. timeseries_ERA5_demErrInvResid.h5
                mask_file : string,
                    mask file, e.g. maskTempCoh.h5
                ramp_type : string,
                    ramp type, e.g. linear, quadratic, no for do not remove ramp
    Returns:    rms_list : list of float,
                    Root Mean Square of deramped input timeseries file
                date_list : list of string in YYYYMMDD format,
                    corresponding dates
                rms_file : string, text file with rms and date info.
    Example:
        import mintpy.utils.utils as ut
        rms_list, date_list = ut.get_residual_rms('timeseriesResidual.h5', 'maskTempCoh.h5')
    r)   r*   r+   r   z
rms_{}.txtFr,   r0   r1   r2   r3   r4   z4
calculating residual RMS for each epoch from file: r7   z(read timeseries residual RMS from file: r:   Nr   )r<   r=   r>   r?   r@   joindirnameabspathrA   rB   rC   rD   r   timeseries_rmsrF   rG   rH   rI   rJ   rK   rL   rM   )	rN   r6   r5   rO   Zrms_filerP   rQ   Zrms_listrR   r$   r$   r%   get_residual_rms]   s2    
rX   maskConnComp.h5c                 C   sX   t | }|d }|dkr,t| j|d}ntd|  dS d|d< tj|||d |S )zDGenerate mask file for non-zero value of input multi-group hdf5 file	FILE_TYPEr   r   z5Only ifgramStack file is supported for now, input is Nmaskr-   metadata)r   r   r   nonzero_maskr<   r   write)Filer-   r   atrkr\   r$   r$   r%   r_      s    
r_   	coherenceFTc               	   C   s  dd }t | }	|	d }
|s:ddt|	d t|	d f}|
dkrF|ntjtj| d }|dkrjd	nd
}||rxdnd7 }|| d }| |rtd || \}}||fS d	tj| }d	|}d	|}d	|}zt
|d}| }|  |r,zdd |D d }W n   d}Y nX n|}zdd |D d }W n   d}Y nX ||kr||krt|| |gdddkrt|d  ||\}}||fW S W n   Y nX d|krd}nd}|
dkrt| }|j
dd |j||||||d\}}|j}|j}|  n|
dkr>t| j||||d \}}nt j| |d!d }|rtj|rtd"|  t j|d#|d$d }tj||t|k< |dk	rd%|||k< d|||k< t|}tj| g}|rtd&|  t
|d'}||| | |  t|}|
dkrX|d( t|D ].}|d)|| || || || |f  q&n4|d* t|D ] }|d+|| || f  qj|  t|d%kr|d }|d }||fS ),a  Read/Calculate Spatial Average of input file.

    If input file is text file, read it directly;
    If input file is data matrix file:
        If corresponding text file exists with the same mask file/AOI info, read it directly;
        Otherwise, calculate it from data file.

        Only non-nan pixel is considered.
    Parameters: File        - string, path of input file
                maskFile    - string, path of mask file, e.g. maskTempCoh.h5
                box         - 4-tuple defining the left, upper, right, and lower pixel coordinate
                saveList    - bool, save (list of) mean value into text file
                reverseMask - bool, perform analysis within masked regions instead of outside of them
                threshold   - float, calculate area ratio above threshold instead of spatial average
    Returns:    meanList    - list for float, average value in space for each epoch of input file
                dateList    - list of string for date info
                              date12_list, e.g. 101120-110220, for interferograms/coherence
                              date8_list, e.g. 20101120, for timeseries
                              file name, e.g. velocity.h5, for all the other file types
    Example:    meanList = spatial_average('inputs/ifgramStack.h5')[0]
                meanList, date12_list = spatial_average('inputs/ifgramStack.h5',
                                                        maskFile='maskTempCoh.h5',
                                                        saveList=True)
    c                 S   sP   t j| tdt}dd |d d df D }dd |d d df D }||fS )Nr:   c                 S   s   g | ]}t |qS r$   )r   .0ir$   r$   r%   
<listcomp>   s     z;spatial_average.<locals>.read_text_file.<locals>.<listcomp>r   c                 S   s   g | ]}|qS r$   r$   re   r$   r$   r%   rh      s     r   )rF   rG   rH   rI   rJ   )fnameZ
txtContentmeanListdateListr$   r$   r%   read_text_file   s    z'spatial_average.<locals>.read_text_filerZ   r   r
   r   r   NZ
SpatialAvgZ	AreaRatioZRevMsk z.txtz;Input file is spatial average txt already, read it directlyz# Data file: {}
z# Mask file: {}
z# AOI box: {}
z# Threshold: {}
rc                 S   s   g | ]}d |kr|qS )z
# AOI box:r$   re   r$   r$   r%   rh      s      z#spatial_average.<locals>.<listcomp>c                 S   s   g | ]}d |kr|qS )z# Mask file:r$   re   r$   r$   r%   rh      s      Fr,   skipz! already exists, read it directlyoffsetT	print_msg)r   r8   r   	useMedianreverseMask	thresholdr   )r8   r   rt   ru   )r   zmask from file: r\   r   r   z-write average value in space into text file: wz'#	DATE12		Mean	Btemp/days	Bperp/m		Num
z%s	%.4f	%8.0f	%8.1f	%d
z#	DATE12		Mean
z%s	%.4f
)r   r   r   r>   r?   r@   basenameendswithr<   r=   open	readlinescloserA   r   spatial_averagepbaseIfgramtbaseIfgramr   r   rB   rF   nannanmeanr`   lenrange) ra   r   r8   r   ZsaveListZcheckAoirt   ru   rl   rb   rc   prefixsuffixZtxtFilerj   rk   Z	file_lineZ	mask_lineZaoi_lineZ
thres_linefllinesZaoi_line_origZmask_line_origrs   objpbasetbasedatar\   ZnumLinerg   r$   r$   r%   r|      s    
$


















r|   c           
      C   sv  t j| |d}|d }|dkrBtd|  t | d }|| fS |dkrtj| d }|s|dkr|d	krtd
}qd|krd}qd|}nF|dkr|| krtj| 	dd 	|d }d|}n
d| }|rtj
|rt |d }	|	|fS |dkr:t| j|d}	d|kr0d|d< d|d< n||d< n|dkrXt|  }	d|d< |rntj|	||d |	|fS )a  Calculate temporal average of multi-temporal dataset, equivalent to stacking
    For ifgramStakc/unwrapPhase, return average phase velocity

    Parameters: File : string, file to be averaged in time
                datasetName : string, dataset to be read from input file, for multiple
                    datasets file - ifgramStack - only
                    e.g.: coherence, unwrapPhase
                updateMode : bool
                outFile : string, output filename
                    None for auto output filename
                    False for do not save as output file
    Returns:    dataMean : 2D array
                outFile : string, output file name
    Examples:   avgPhaseVel = ut.temporal_average('ifgramStack.h5', datasetName='unwrapPhase')[0]
                ut.temporal_average('ifgramStack.h5', datasetName='coherence',
                                    outFile='avgSpatialCoh.h5', updateMode=True)
    r[   rZ   )r   r   zBWARNING: input file is not multi-temporal file: {}, return itself.r   Nr   r   rd   zavgSpatialCoh.h5unwrapPhasezavgPhaseVelocity.h5zavg{}.h5r   zavgDisplacement{}.h5velocityzm/yearUNITdisplacementr]   )r   r   r<   r=   r   r>   r?   r@   rw   splitrB   r   temporal_averager   r   r`   )
ra   r   Z
updateModer9   rb   rc   r   extZprocessMarkZdataMeanr$   r$   r%   r   3  sF     





r   c           
      C   s   | sg S t | tr| g} dd | D } g }tt| D ]2}| | }t|}|ttt|t| 7 }q6|r|dd |D }|dk	rt|D ]`}t	|}|dkrd|
 kr|| q|dkrd|
 kr|| qd|}	t|	q|S )	aR  Get all existed files matching the input list of file pattern
    Parameters: file_list - string or list of string, input file/directory pattern
                abspath - bool, return absolute path or not
                coord - string, return files with specific coordinate type: geo or radar
                    if none, skip the checking and return all files
    Returns:    file_list_out - list of string, existed file path/name, [] if not existed
    Example:    file_list = get_file_list(['*velocity*.h5','timeseries*.h5'])
                file_list = get_file_list('timeseries*.h5')
    c                 S   s   g | ]}|d kr|qS Nr$   )rf   xr$   r$   r%   rh     s      z!get_file_list.<locals>.<listcomp>c                 S   s   g | ]}t j|qS r$   )r>   r?   rV   re   r$   r$   r%   rh     s     N)geor   )ZradarrdrZrdcz"un-recognized input coord type: {})
isinstancerJ   r   r   globsortedrM   setr   r   r   remover=   
ValueError)
	file_listrV   coordZfile_list_outrg   Zfile0Z
file_list0ri   rb   rP   r$   r$   r%   get_file_listu  s0    





r   c                    s   | sDdddddddg}dd	d
g}g } |D ] |  fdd|D 7 } q(g }zt | }W n*   |rxtd td t|  Y dS X d}|D ]H}t|}dD ]4}	z"tj||	ddd }
|}W  qW q   Y qX qq|s|rtd dS |rtj|}|S )a  Find lookup table file with/without input file pattern
    Parameters: filePattern - list of str
                abspath     - bool, return absolute path or not
                print_msg   - bool, printout message or not
    Returns:    outFile     - str, path of the lookup file
    zgeometryRadar.h5zgeometryGeo_tight.h5zgeometryGeo.h5zgeomap*lks_tight.transzgeomap*lks.transzsim*_tight.UTM_TO_RDCzsim*.UTM_TO_RDCinputsrm   z	../inputsc                    s   g | ]}t j |qS r$   r>   r?   rT   )rf   ri   rU   r$   r%   rh     s     z#get_lookup_file.<locals>.<listcomp>z-ERROR: No geometry / lookup table file found!zIt should be like:N)r   
rangeCoordF)r   rr   r   z.No lookup table info range/lat found in files.)r   r<   r   r   r   r>   r?   rV   )ZfilePatternrV   rr   ZfileListZdirListZ
existFilesr9   ri   rb   dsNamedsetr$   r   r%   get_lookup_file  sN       



r   r   c                    s   t | tr| g} | D ]}|tkrtd|qs<t fdddD }t||d}t|dkrv|rrt	d dS t
|D ]$ t fd	d
| D r~|  q~t|dkr|rt	d|  dS |d }|rtj|}|S )z4Find geometry file containing input specific datasetz&unrecognized geometry dataset name: {}c                    s   g | ]}t j |qS r$   r   re   )work_dirr$   r%   rh     s     z%get_geometry_file.<locals>.<listcomp>)z*geometry*.h5z*/*geometry*.h5z../*/geometry*.h5)r   r   zNo geometry file found.Nc                 3   s   | ]}|t  kV  qd S r   )r   get_dataset_list)rf   r   )ri   r$   r%   	<genexpr>  s     z$get_geometry_file.<locals>.<genexpr>z&No geometry file with dataset {} found)r   rJ   r   r   r=   r>   getcwdr   r   r<   rM   anyr   r?   rV   )Z	dset_listr   r   rV   rr   r   
fname_listr   r$   )ri   r   r%   get_geometry_file  s0    
r   =c                 C   s|  d}t | }| D ]$\}}|| kr|| |krd}q|sPtd|   | S | d }t|d}t| dD ]}	dd |	 |d	D }
|	d
sXt	|
d	krX|
d }t
|
d	 dddd  }|| krX|| |krX|}dD ]}||d|}q|d | }t||	d }|||| }|	||d	}	td||||  ||	 ql|  t||  | S )zEUpdate option value in template_file with value from input extra_dictFTz)No new option value found, skip updating z.tmprv   rn   c                 S   s   g | ]}|  qS r$   )stripre   r$   r$   r%   rh     s     z(update_template_file.<locals>.<listcomp>r   )%#r   
rm   r   )r	   []()z\{}z[\s]*z    {}: {} --> {})r   read_templateitemsr   r<   ry   r   r   
startswithr   rJ   replacer=   refindallr`   r{   shutilmove)Ztemplate_fileZ
extra_dict	delimiterupdateZ	orig_dictkeyvalueZtmp_fileZf_tmplinecZvalue2searchsymbolZold_value_strZnew_value_strr$   r$   r%   update_template_file  s8    

 r   c                 C   s   t | }t||}|s$td | S t| d}t| D ]p\}}|dksT|dkrz"|j	| |rttd
| W q   Y qX q<t||j|< |r<td
|t| q<|  | S )a#  Add/update input attribute into File
    Parameters: File - string, path/name of file
                atr_new - dict, attributes to be added/updated
                    if value is None, delete the item from input File attributes
    Returns:    File - string, path/name of updated file
    zeAll updated (removed) attributes already exists (do not exists) and have the same value, skip update.zr+NoneNz	remove {}z{} = {})r   r   update_attribute_or_notr<   h5pyra   iterr   attrspopr=   rJ   r{   )ra   atr_newrr   rb   r   fr   r   r$   r$   r%   add_attribute$  s&    

r   c           	      C   s8  | s| ddfS g }g }| D ]*}t |}||d  ||d  q|sRt|}|s^t|}t| }||t|ks||t|kr.td td td td||f  td tt| D ]H}|| |ks|| |krtd	| | || || f  |	| |  qtd
t
t|  td |||fS )zXCheck file size in the list of files, and drop those not in the same size with majority.Nr
   r   z-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%z2WARNING: Some files may have the wrong dimensions!z$All files should have the same size.z9The width and length of the majority of files are: %s, %szNBut the following files have different dimensions and thus will not be loaded:z%s    width: %s  length: %sz
Number of files left: z,%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%)r   r   appendmost_commonrM   countr   r<   r   r   rJ   )	r   Z
mode_widthZmode_lengthZ
width_listZlength_listri   rb   Zfname_list_outrg   r$   r$   r%   check_file_sizeG  s@    

r   c                 C   s4   zt | |dd }t| W n   d}Y nX |S )a  Check if any file in the file list 1) exists and 2) readable
    Parameters: file_list : str or list(str), file name with/without wildcards
                abspath   : bool, return absolute file name/path or not
    Returns:    file_path : string, found file name/path; None if not.
    )rV   r   N)r   r   r   )r   rV   filer$   r$   r%   is_file_existr  s    
r   c                 C   s   | sdS t | tr| g} tdd | D s.dS |rzt| d }|d }W n2   |rjtd| d  t| d  Y dS X |rt	|}|rt
dd |D }td	d | D }||krdS |rtd
| | dS )a  Check whether to update out_file or not.
    return run if any of the following meets:
        1. out_file is empty, e.g. None, []
        2. out_file is not existed
        3. out_file is not readable by readfile.read_attribute() when check_readable=True
        4. out_file is older than in_file, if in_file is not None
    Otherwise, return skip.

    If in_file=None and out_file exists and readable, return skip

    Parameters: out_file : string or list of string, output file(s)
                in_file  : string or list of string, input file(s)
                check_readable : bool, check if the 1st output file has attribute 'WIDTH'
                print_msg      : bool, print message
    Returns:    run/skip : str, whether to update output file or not
    Example:    if ut.run_or_skip(out_file='timeseries_ERA5_demErr.h5', in_file='timeseries_ERA5.h5'):
                if ut.run_or_skip(out_file='exclude_date.txt',
                                  in_file=['timeseries_ERA5_demErrInvResid.h5',
                                           'maskTempCoh.h5',
                                           'smallbaselineApp.cfg'],
                                  check_readable=False):
    r0   c                 s   s   | ]}t j|V  qd S r   )r>   r?   rB   re   r$   r$   r%   r     s     zrun_or_skip.<locals>.<genexpr>r   r
   z'{} exists, but can not read, remove it.c                 S   s   g | ]}t j|qS r$   r>   r?   getmtimere   r$   r$   r%   rh     s     zrun_or_skip.<locals>.<listcomp>c                 S   s   g | ]}t j|qS r$   r   re   r$   r$   r%   rh     s     z({} exists and is newer than {} --> skip.ro   )r   rJ   allr   r   r<   r=   r>   r   r   maxmin)r-   r.   r/   rr   rb   widthZt_inZt_outr$   r$   r%   rA     s2    
rA   "defaults/smallbaselineApp_auto.cfgc           	      C   s   t jt jtj|}t|}d}| |d	 }|dkrF|| }|dkrVd|d< | 
 D ](\}}|dkr^|| kr^|| | |< q^dddddd	}| 
 D ](\}}|	 }|| kr|| | |< q| S )
z7Replace auto value based on the input auto config file.zmintpy.compute.clusterautolocalZ40zmintpy.compute.numWorkerTFN)yestruer)   falsenone)r>   r?   rT   rU   mintpy__file__r   r   getlowerr   r   )	ZtemplateDictZ	auto_fileZtemplateAutoFileZtemplateAutoDictZcluster_keyZclusterr   r   ZspecialValuesr$   r$   r%   check_template_auto_value  s,    
r   c                 C   sj  t   }t| }|d }t|d }	t|d }
td||  |sbtj| \}}d||}|dkrn| }tj	|rt
|d }td|  ntj|	|
ftjd	}td
 d}|r6tjtj| d }tjtj|d|}t|d6}|d|  |d| |d| W 5 Q R X |dkr@tj|| dd td t|  }t|}tj|d}t|D ]}|rt|d}|d||  W 5 Q R X tj
| || dd }t|||||dd }tj||d||d d|	d|
gdd |j|d d|d |d q|  td| n |dkrt| }|jdd  |shd!}t !| d8}|| }d"|}||" kr|| }td#| n,|j#||j$|	|
ftj%ddd$}td%| tj|j$d}t|j$D ]}|r.t|d }|dt&|j'|  W 5 Q R X ||ddddf }t|||||dd }|||ddddf< |j|d d|d |j$d q|  td|  W 5 Q R X n|rt|d}|d|d  W 5 Q R X |s|d&krd&}tj
| |dd }t|||||dd }td'| tj||| d( t(t   | d)\}}td*|| |S )+a   Remove ramp from each 2D matrix of input file
    Parameters: fname     : str, data file to be derampped
                ramp_type : str, name of ramp to be estimated.
                mask_file : str, file of mask of pixels used for ramp estimation
                out_file  : str, output file name
                datasetName     : str, output dataset name, for ifgramStack file type only
                save_ramp_coeff : bool, save the estimated ramp coefficients to text file
    Returns:    out_file  : str, output file name
    rZ   r   r
   zremove {} ramp from file: {}z	{}_ramp{}r   r   zread mask file: r:   zuse mask of the whole areaNzrampCoeff_{}.txtrv   z# input  file: {}
z# output file: {}
z# ramp type: {}
r   T)ref_filerr   z,estimating phase ramp one date at a time ...)maxValueaz{}    r[   )r5   r^   
coeff_filer   F)r   blockrr   z{}/{})r   zfinished writing to file: {}rq   r   z{}_rampzaccess HDF5 dataset /{})shaper;   chunkscompressionzcreate HDF5 dataset /{}r   zwriting >>> {})r-   r   <   z'time used: {:02.0f} mins {:02.1f} secs.))timer   r   r   r<   r=   r>   r?   r@   rB   r   rF   onesbool_rw   rT   rU   ry   r`   r   layout_hdf5r   get_date_listr   r   progressBarr   r   write_hdf5_blockr   r{   r   r   ra   r   create_dataset	numIfgramrK   rJ   
date12Listdivmod)ri   r5   r6   r-   r   Zsave_ramp_coeff
start_timerb   rc   lengthr   fbasefextr\   r   r   rR   num_dateprog_barrg   r   r   dsZ	dsNameOutZdsOutmsr$   r$   r%   rD     s    


"


$$rD   )N)r'   r(   )r'   r(   )rY   N)rd   NNFTFN)rd   FN)FN)NFT)Nr   TT)r   )NN)T)NTT)r   )NNNF)$r>   r   r   r   r   r   numpyrF   r   mintpy.objectsr   r   r   r   mintpy.utilsr   r   r   mintpy.utils.utils0r&   rS   rX   r_   r|   r   r   r   r   r   dictr   r   r   rA   r   rD   r$   r$   r$   r%   <module>   s@   

-
3
        
 
B
*
5
"
.#
+

9
#