U
     xbM                     @   s   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
 d dlmZmZmZ d dlT d dlT d dlm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dS )$    N)map_coordinates)geometryDatasetNamesgeometryifgramStack
timeseries)ptimereadfile	attribute)*)
coordinate)resample./TFc                    s  | st  } t j| } t j| d}dddg}t|ddrt|  jdd t fd	d
|D rd| d}|d|7 }t	|d j
krd j
krtd|  nttjt tj|t|}d| krdnd}|d }t j| dd|  d}	td }
t|	ddrPt|	  jdd |
 j
krft	d|
 d|	 nttjt tj|	t j| d}t|d|d}|dkr4|dk	rt|  jdd |dkrtdd }n,|d krtdd! }nd"| d#}t||D ]&}
|
 j
krtd|
 d| qnttjt tj|ntd$ t j| d%}d}
t|ddrt|  jdd |
 j
krt	d|
 d| d j
krd j
krtd|  nd}|r|rt j|n|}|	rt j|	n|	}	|r t j|n|}|rt j|n|}|rd&| }|d'| d(7 }|d)| 7 }||rZd*| nd+7 }|d,|	 7 }|d-| 7 }|d.7 }t| ||	||fS )/a  Check the loaded input files, following two rules:
        1. file existance
        2. file attribute readability

    Parameters: work_dir    - str, MintPy working directory
                print_msg   - bool, print out message
    Returns:    stack_file  - str, path to the interferogram stack file
                geom_file   - str, path to the geometry file
                lookup_file - str, path to the look up table file, for radar-coord dataset only.
                ion_file    - str, path to the ionosphere stack file
    Example:    work_dir = os.path.expandvars('./FernandinaSenDT128/mintpy')
                stack_file, geom_file, lookup_file = ut.check_loaded_dataset(work_dir)[:3]
    zinputs/ifgramStack.h5unwrapPhaserangeOffsetazimuthOffsetT)abspathF	print_msgc                 3   s   | ]}| j kV  qd S )N)datasetNames).0xobj I/home/exouser/operations/rsmas_insar/sources/MintPy/mintpy/utils/utils.py	<genexpr>8   s     z'check_loaded_dataset.<locals>.<genexpr>z$required dataset is missing in file z:
z OR 	coherencez(WARNING: "coherence" is missing in file Y_FIRSTZGEOZRADAR	PROCESSORinputsr   z.h5r   zrequired dataset "z" is missing in file zinputs/geometry*.h5)r   r   N)isceZdoris      )gammaroipac   zUnknown InSAR processor: z to locate look up table!z8Input data seems to be geocoded. Lookup file not needed.zinputs/ionStack.h5z0Loaded dataset are processed by InSAR software: z
Loaded dataset are in z coordinatesz
Interferogram Stack: z
Ionosphere    Stack:  z
Geometry      File : z
Lookup Table  File : z3
--------------------------------------------------)osgetcwdpathr   joinZis_file_existr   openall
ValueErrorr   printFileNotFoundErrorerrnoENOENTstrerrorr   read_attributekeys
capitalizer   r   Zget_lookup_fileAttributeError	Exceptionrelpath)Zwork_dirr   r8   Z
stack_fileZdnamesmsgatr
coord_type	processor	geom_filednamelookup_fileZion_filer   r   r   check_loaded_dataset   s    






r@   r!   mmeanc                 C   s   t |}t||d}|| |dd \}}|
rRtd| | td|| d\}}|dk	rz|||dd \}}t|||||||||	dd	
\}}}|||fS )
a   Read time-series of one pixel with input lat/lon
    Parameters: lat/lon     - float, latitude/longitude
                ts_file     - string, filename of time-series HDF5 file
                lookup_file - string, filename of lookup table file
                ref_lat/lon - float, latitude/longitude of reference pixel
                zero_first  - bool, shift the time-series so that it starts from zero
                win_size    - int, windows size centered at point of interest
                unit        - str, output displacement unit
                method      - str, method to calculate the output displacement and its dispersity
    Returns:    dates       - 1D np.ndarray of datetime.datetime objects, i.e. datetime.datetime(2010, 10, 20, 0, 0)
                dis         - 1D np.ndarray of float32, displacement
                dis_std     - 1D np.ndarray of float32, displacement dispersity
    )r?   r      zinput lat / lon: {} / {}zcorresponding y / x: {} / {})NNNF)ref_yref_x
zero_firstwin_sizeunitmethodr   )r   r3   r   Z	geo2radarr.   formatread_timeseries_yx)latlonts_filer?   ref_latref_lonrF   rG   rH   rI   r   r:   coordyr   rD   rE   datesdisdis_stdr   r   r   read_timeseries_lalo   s&    
rV   c
                 C   s  t |}
|
jdd t|
jd }t|}|	rBtd| | || |d | d f}t	j
||dd }d}|dkrt|d }|| | | || d | | d f}t	j
||dd |
jd	}|d
krtj|dd}tj|dd}n0|dkr
tj|dd}t|}ntd||dk	rL|||d |d f}|t	j
||dd 8 }|r^||d 8 }|dkrjnb|dkr|d9 }|dkrdn|d }n8|dkr|d9 }|dkrdn|d }ntd||||fS )aE   Read time-series of one pixel with input y/x
    Parameters: y/x        - int, row/column number of interest
                ts_file    - string, filename of time-series HDF5 file
                ref_y/x    - int, row/column number of reference pixel
                zero_first - bool, shift the time-series so that it starts from zero
                win_size   - int, windows size centered at point of interest
                unit       - str, output displacement unit
                method     - str, method to calculate the output displacement and its dispersity
    Returns:    dates      - 1D np.ndarray of datetime.datetime objects, i.e. datetime.datetime(2010, 10, 20, 0, 0)
                dis        - 1D np.ndarray of float32, displacement
                dis_std    - 1D np.ndarray of float32, displacement dispersity
    Fr   r   zinput y / x: {} / {}r!   )boxNrC   rB   )axismedianzun-recognized method: {}rA   cmg      Y@mmg     @@zun-supported output unit: {})r   r+   r   date_list2vectordateListnparrayr.   rJ   r   readintreshapenumDatenanmeannanstd	nanmedianmedian_abs_deviationr-   )rR   r   rN   rD   rE   rF   rG   rH   rI   r   r   rS   rW   rT   rU   bufZbox_winZdis_winZref_boxr   r   r   rK      sF    

$





rK   nearestc                    s  |  }|\}}|\}}t|d t|d   t fddt||g||gD sd}	|	d|7 }	|	d|7 }	|	d 7 }	t|	tt|| || }
tj|||
tj	d	}tj|||
tj	d	}|d
kr| t
|tjt
|tjf }nbdddd}|| krBd|}	|	d| 7 }	t|	||   }t| t||f|d}d}d}d| krt|j||gdd\}}|| d }t|d tj d | t|tj d  }t|d tj d | }n8zt|}t|}W n" tk
r"   d}d}d}Y nX t|| | || | }t| }||dk9 }i }|| |d< || |d< || |d < || |d!< ||d"< |S )#a{  Extract 2D matrix (z) value along the line [x0,y0;x1,y1]
    Link: http://stackoverflow.com/questions/7878398/how-to-extract-an-arbitrary-line-of-values-from-a-numpy-array

    Parameters: z : (np.array) 2D data matrix
                atr : (dict) attribute
                start_yx : (list) y,x coordinate of start point
                end_yx : (list) y,x coordinate of end   point
                interpolation : str, sampling/interpolation method, including:
                    'nearest' - nearest neighbour
                    'linear'  - linear  spline interpolation (order of 1)
                    'cubic'   - cubic   spline interpolation (order of 3)
                    'quintic' - quintic spline interpolation (order of 5)

    Returns:    transect: (dict) containing 1D matrix:
                    'X' - 1D np.array for X/column coordinates in float32
                    'Y' - 1D np.array for Y/row.   coordinates in float32
                    'value' - 1D np.array for z value in float32
                    'distance' - 1D np.array for distance in float32

    Example: transect = transect_yx(dem, demRsc, [10,15], [100,115])
    LENGTHWIDTHc                 3   sB   | ]:\}}d |  kok n  o8d |  ko4 k n  V  qdS )r   Nr   )r   ijlengthwidthr   r   r     s     ztransect_yx.<locals>.<genexpr>z-input start/end point is out of data coveragez
start_yx: {}z

end_yx:{}z
data size: ({}, {})dtyperj   r!   r"   r%   )linearZcubicZquinticz%un-supported interpolation method: {}z
available methods: {})orderg    TXArA   r   rR   r;   g       @X_STEP     f@   Y_STEPpixelg        YXvaluedistanceZdistance_unit)lowerrb   r,   ziprJ   r-   r_   hypotlinspacefloat32rintastyper4   r   vstackr   Zyx2lalofloatpicosrange_ground_resolutionazimuth_ground_resolutionKeyErrorisnan)zr:   Zstart_yxZend_yxinterpolationy0x0y1x1r9   Znum_ptsysxsZz_lineZinterpolate_name2orderZinterp_orderearth_radiusZ	dist_unitlat0lat1lat_cx_stepy_stepZ	dist_linemasktransectr   ro   r   transect_yx   sf    &
*
.

r   c                 C   s`   t |}|j|d |d gdd\}}|j|d |d gdd\}}	t| |||g||	g|}
|
S )zAExtract 2D matrix (z) value along the line [start_lalo, end_lalo]r   rL   rv   r!   rM   )r   Zlalo2yxr   )r   r:   
start_laloend_lalor   rQ   r   r   r   r   r   r   r   r   transect_lalo]  s
    r   c                 C   s  i }d}g |d< t t|D ]}|| d || d  }}d| krVt| |||}nt| |||}|d  |7  < |dkr| D ]\}	}
tj|
tjd||	< qn(| D ]\}	}
t	||	 |
f||	< q|d 
| |d d }qtj|d tjd|d< |S )a  Extract 2D matrix (z) value along multiple lines
    Parameters: z     : 2D np.ndarray in size of (l,w)
                atr   : dict, metadata of matrix z
                lines : list of lines with each line is defined as:
                    [[lat0, lon0], [lat1, lon1]] for geo coordinates
                    [[y0, x0], [y1, x1]] for radar coordinates
    Returns: transect : (dict) containing 1D matrix:
                    'X' - 1D np.array for X/column coordinates in float32
                    'Y' - 1D np.array for Y/row.   coordinates in float32
                    'value' - 1D np.array for z value in float32
                    'distance' - 1D np.array for distance in float32
    r   start_distancer!   r   r   rr   rX   )rangelenr4   r   r   itemsr_   r`   r   concatenateappend)r   r:   linesr   r   rm   r   r   segkeyr~   r   r   r   transect_linesf  s$    r   radc                 C   s|  t d|  t| }t d|  tj| ddd }dt| krxt d|  t d tj| ddd }t|}n&t d	 tj|j	tj
d
t|d  }d| krHt d t d t| | d}|  |  |jd }|j||d |d |d |d f d}|j||d |d |d |d f d}tj||d}|d  ds.t|d t|d  }}	t|d }
t|d }t|d }t|d }|
||  }|||	  }t|d ||
\}}t|d ||\}}|| | }|| |	 }||d< ||d< ||d< ||d< d|d< d|d< tj||dk< tj||dk< |d rr|tjd! 9 }|tjd! 9 }|||fS )"a  Prepare LOS geometry data/info in geo-coordinates.

    Parameters: geom_file  - str, path of geometry file
                unit       - str, rad or deg, output angle unit
    Returns:    inc_angle  - 2D np.ndarray, incidence angle in radians / degrees
                head_angle - 2D np.ndarray, heading   angle in radians / degrees
                atr        - dict, metadata in geo-coordinate
    z5prepare LOS geometry in geo-coordinates from file: {}z!read incidenceAngle from file: {}incidenceAngle)datasetNamer   azimuthAnglez!read azimuthAngle   from file: {}z&convert azimuth angle to heading anglez3use the HEADING attribute as the mean heading anglerr   HEADINGr   z2--------------------------------------------------z,geocoding the incidence / heading angles ...)Zlut_fileZsrc_filer!   r"   rC   )Zsrc_data)res_objY_UNITdegrk   rl   X_FIRSTrz   rw   OG_FILE_PATHdegreesX_UNITZ   r   rx   )r.   rJ   r   r3   ra   get_dataset_listazimuth2heading_angler_   onesshaper   r   r4   r   r+   prepareZsrc_box_listZrun_resampleattrZupdate_attribute4radar2geor   
startswithrb   	to_latlonnanr   )r=   rH   r:   	inc_angleaz_angle
head_angler   rW   rp   rq   NWr   r   SEr   lon0r   lon1lat_steplon_stepr   r   r   prepare_geo_los_geometry  sZ    



,,r   )r   TF)NNNTr!   rA   rB   T)NNTr!   rA   rB   T)rj   )rj   )r   )r'   r0   numpyr_   Zscipy.ndimager   mintpy.objectsr   r   r   r   mintpy.utilsr   r   r	   r   Zmintpy.utils.utils0Zmintpy.utils.utils1Zmintpy.objects.coordr   Zmintpy.objects.resampler   r@   rV   rK   r   r   r   r   r   r   r   r   <module>
   s6   
u          
'        
D
_
	-