U
     xb                  3   @   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m	Z	m
Z
 ejejejejejejejejejejejejejejejejejejejejejdZdddgZdddd	d
dgZddddddddddddgZddddddddd d!d"d#d$d%gZd&d'd'd&d'd(d(d(d(d'd)d*d*d'd'd*d*d)d'd'd'd)d)d)d)d)d)d)d'd+d,d'd-d-d-d-d-d-d-d'd'd&d&d&d'd)d)d)d'd'd.2ZG d/d dZG d0d1 d1ZG d2d3 d3ZG d4d5 d5ZG d6d dZdS )7    N)ptime	time_func)boolbyteflagintint16shortint32int64longfloatfloat32float_float64complex	complex64Zcpx_float32cfloatZcfloat32
complex128complex_Zcpx_float64
timeseriesHDFEOSgiantTimeseriesrawtroposphericDelaytopographicResidualrampdisplacementheightlatitude	longitude
rangeCoordazimuthCoordincidenceAngleazimuthAngleslantRangeDistance
shadowMask	waterMask
commonMaskbperpunwrapPhaseZ!unwrapPhase_bridging_phaseClosureZunwrapPhase_bridgingZunwrapPhase_phaseClosure	coherenceconnectComponent	wrapPhase	magnitudeazimuthOffsetazimuthOffsetStdrangeOffsetrangeOffsetStd	offsetSNRZrefPhaseZradian1Zpixelmdegreezm/yearzm/year^2mm)2r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r   r   r   r   r   r   temporalCoherenceZvelocityZaccelerationmaskr   reconsrawtssar_aps	igram_apsfigramigramcmaskifgcntZunwr   flatZcorZdemZhgtZhgt_simr.   Z	intensityc                   @   s   e Zd ZdZd ddZd!ddZd"dd	Zd
d Zdd Zdd 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 ))r   a  
    Time-series object for displacement of a set of SAR images from the same platform and track.
    It contains three datasets in root level: date, bperp and timeseries.

    File structure: https://mintpy.readthedocs.io/en/latest/api/data_structure/#timeseries
    Nc                 C   s   || _ d| _d S )Nr   filenameselfrD    rH   K/home/exouser/operations/rsmas_insar/sources/MintPy/mintpy/objects/stack.py__init__   s    ztimeseries.__init__Tc                 C   s<   z*| j   |r(tdtj| j W n   Y nX d S Nzclose timeseries file: {}fcloseprintformatospathbasenamerD   rG   	print_msgrH   rH   rI   rN      s    
ztimeseries.closec              	      s~  |r t d jtj j        	   j
 j  _t jdF}z,|d d d   _  j j j 8  _W n   d  _Y nX W 5 Q R X t jd  _t fdd jD  _d jkstdd	  jD r(d
 j kr(t jd
 tfdd jD  _tjdd  j j j  D tjd _dd  jD  _ fdd jD  _d S )Nopen {} file: {}rr)   r   c                    s   g | ]}t j| jqS rH   dtdatetimestrptime
dateFormat.0irG   rH   rI   
<listcomp>   s     z#timeseries.open.<locals>.<listcomp>Tc                 s   s"   | ]}|j d ko|jd kV  qdS )r   N)hourminuter]   rH   rH   rI   	<genexpr>   s     z"timeseries.open.<locals>.<genexpr>CENTER_LINE_UTCc                    s   g | ]}|t j d  qS ))seconds)rY   	timedeltar]   )utc_secrH   rI   ra      s     c                 S   s   g | ]}|j |jd   qS iQ daysrg   r]   rH   rH   rI   ra      s   dtypec                 S   s$   g | ]}|j | jd  d  qS )        v@)year	timetupletm_ydayr]   rH   rH   rI   ra      s     c                    s   g | ]}d   j|qS z{}-{})rP   rE   r]   r`   rH   rI   ra      s     ) rO   rP   rE   rQ   rR   rS   rD   get_metadataget_sizeget_date_listlengthwidthnumPixelh5pyFilepbaserefIndexr   get_date_str_formatdateListr\   nparraytimesallmetadatakeysr   r   tbaseyearList	sliceList)rG   rU   rM   rH   )rG   ri   rI   open   s4     
ztimeseries.openc              	   C   s   t | jd"}t|j| _|d d d  }W 5 Q R X | j D ]4\}}z|d| j|< W q@   || j|< Y q@X q@dd |D }d| j kr|d | jd< |	| jd | _
|d | jd< |d	 | jd
< | jS )NrW   dateutf8c                 S   s   g | ]}| d qS r   decoder]   rH   rH   rI   ra      s     z+timeseries.get_metadata.<locals>.<listcomp>REF_DATEr   
START_DATEEND_DATE)r{   r|   rD   dictattrsr   itemsr   r   indexr~   rG   rM   dateskeyvaluer   rH   rH   rI   ru      s    ztimeseries.get_metadatac              	   C   sJ   t | jd&}|| j jdd  \| _| _| _W 5 Q R X | j| j| jfS )NrW   )r{   r|   rD   rE   shapenumDaterx   ry   rG   rM   rH   rH   rI   rv      s    *ztimeseries.get_sizec              	   C   s<   t | jd"}dd |d d d  D | _W 5 Q R X | jS )NrW   c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra      s     z,timeseries.get_date_list.<locals>.<listcomp>r   r{   r|   rD   r   r   rH   rH   rI   rw      s    &ztimeseries.get_date_listc           
   	   C   s<  |rt d| j| j | jdd |r0|dkr6g }nt|trF|g}dd |D }t| jd}|| j }t|tj	r|| j }t
j| jt
jd}|sd	|d
d
< n|D ]}d	|| j|< q|d
krdd| j| jg}|d
d
|d |d |d |d f | }	|r.tdd |	jD r.t
|	}	W 5 Q R X |	S )a  Read dataset from timeseries file
        Parameters: self : timeseries object
                    datasetName : (list of) string in YYYYMMDD format
                    box : tuple of 4 int, indicating x0,y0,x1,y1 of range
        Returns:    data : 2D or 3D dataset
        Examples:   from mintpy.objects import timeseries
                    tsobj = timeseries('timeseries_ERA5_demErr.h5')
                    data = tsobj.read(datasetName='20161020')
                    data = tsobj.read(datasetName='20161020', box=(100,300,500,800))
                    data = tsobj.read(datasetName=['20161020','20161026','20161101'])
                    data = tsobj.read(box=(100,300,500,800))
        !reading {} data from file: {} ...FrU   r   c                 S   s    g | ]}| d d ddqS )r    -replacer]   rH   rH   rI   ra      s     z#timeseries.read.<locals>.<listcomp>rW   rm   TNr   ro         c                 s   s   | ]}|d kV  qdS ro   NrH   r]   rH   rH   rI   re     s     z"timeseries.read.<locals>.<genexpr>)rO   rP   rE   rD   r   
isinstancestrr{   r|   Groupr   zerosr   bool_r   r   ry   rx   anyr   squeeze)
rG   datasetNameboxr   rU   rM   dsdateFlagedatarH   rH   rI   read   s>    


  ztimeseries.readc              	   C   s  |s
| j }|rt|}|jdd |dkr0|j}|dkr>|j}|dkrL|j}|dkrzt|d}	|	td  j	}W 5 Q R X |j
dd tj|tjd}tj|tjd}tj|tjd}t|}| j|d< tjtj|}
tj|
st|
 td|
 td	| t|d
}tdjt|j|j|d |jd|d|d tdt|j|j |jd|d |jdkrtdt|j|j |jd|d | D ]\}}t||j|< qW 5 Q R X td| |S )a7  
        Parameters: data  : 3D array of float32
                    dates : 1D array/list of string in YYYYMMDD format
                    bperp : 1D array/list of float32 (optional)
                    metadata : dict
                    outFile : string
                    refFile : string
                    compression : string or None
        Returns: outFile : string
        Examples:
            from mintpy.objects import timeseries

            ##Generate a new timeseries file
            tsobj = timeseries('timeseries.h5')
            timeseries.write(data, dates=dateList, bperp=bperp, metadata=atr)

            ##Generate a timeseries with same attributes and same date/bperp info
            tsobj = timeseries('timeseries_demErr.h5')
            timeseries.write(data, refFile='timeseries.h5')
        Fr   NrW   r   rm   	FILE_TYPEzcreate directory: {}z+create timeseries HDF5 file: {} with w modewzIcreate dataset /timeseries of {t:<10} in size of {s} with compression={c})tscr   T)r   chunkscompressionz2create dataset /dates      of {:<10} in size of {}r   )r   rH   z2create dataset /bperp      of {:<10} in size of {}r)   zfinished writing to {})rD   r   r   r   r   r}   r{   r|   timeseriesDatasetNamesr   rN   r   r   r   string_r   rE   rQ   rR   dirnameabspathisdirmakedirsrO   rP   r   rn   r   create_datasetr   r   )rG   r   outFiler   r)   r   ZrefFiler   ZrefobjrfZoutDirrM   r   r   rH   rH   rI   
write2hdf5  sZ    

ztimeseries.write2hdf5c              
   C   s   |   }|r:t|  }td|  tj|dd|dkf< tj|dd| _d}|d| j7 }|d|7 }|d	7 }|st	j
t	j
t	j
| jd
t	j
t	j
| jd }tj|tt| jdd| jddfdd|d td| |S )zxCalculate the standard deviation (STD) for acquisition of time-series,
           output result to a text file.
        read mask from file: Nr   ro   r   axisz@Standard Deviation in space for each acquisition of time-series
Timeseries file: {}
Mask file: {}
zDate		STD (m)z
std_{}.txtr   ro   %s	fmt	delimiterheaderz$save timeseries STD to text file: {})r   singleDatasetrO   r   nannanstdstdrP   rD   rQ   rR   joinr   r   splitextrS   savetxthstackr   r   reshape)rG   maskFiler   r   r9   r   rH   rH   rI   timeseries_stdb  s*    ,  ztimeseries.timeseries_stdc           
   
   C   s  |   }t|}|r8tj|r8td|  t| }t	|tj
 | _td| j| j tj|d}t|D ]x}| jd|| dd}|rtj|rtj
||dk< ttjt|dd	| j|< |j|d
 d|d
 |d qr|  d}	|	d| j7 }	|	d|7 }	|	d7 }	|s`tjtjtj| jdtjtj| jd }tj|tt| j dd
| j dd
fdd|	d td| |S )zyCalculate the Root Mean Square for each acquisition of time-series
            and output result to a text file.
        r   r   ZmaxValuez{}F)r   rU   r   )r   ro   r   ro   {}/{}suffixz>Root Mean Square in space for each acquisition of time-series
r   r   zDate		RMS (m)z
rms_{}.txtr   r   r   r   z$save timeseries RMS to text file: {})!rw   lenrQ   rR   isfilerO   r   r   r   r   r   ZrmsrP   rE   rD   r   progressBarrangesqrtnanmeansquareupdaterN   r   r   r   r   rS   r   r   r   r   r   )
rG   r   r   	date_listnum_dater9   prog_barr_   r   r   rH   rH   rI   timeseries_rms{  s<      ,  ztimeseries.timeseries_rmsFc                 C   s   | j dd | j|d}|rVtj|rVtd|  t|j|d}tj||t	|k< |d k	rvd|||k< d|||k< tj
|dd}|| jfS )	NFr   r   r   ro   r   r   r   )r   r   rQ   rR   r   rO   r   r   r   r   r   r   )rG   r   r   reverseMask	thresholdr   r9   dmeanrH   rH   rI   spatial_average  s    ztimeseries.spatial_averagec                 C   s:   t d| j | jdd | jdd}tj|dd}|S )Nz7calculating the temporal average of timeseries file: {}Fr   )r   r   r   )rO   rP   rD   r   r   r   r   )rG   r   r   rH   rH   rI   temporal_average  s
    ztimeseries.temporal_averagebl_list.txtc              	   C   st   | j dd dd | jD }| j }td| t |d,}t||D ]\}}|d|| qJW 5 Q R X |S )z2Generate bl_list.txt file from timeseries h5 file.Fr   c                 S   s   g | ]}|d d qS )r      rH   r]   rH   rH   rI   ra     s     z0timeseries.save2bl_list_file.<locals>.<listcomp>z$write baseline list info to file: {}r   z{}	{}
)r   r   r}   tolistrO   rP   zipwrite)rG   out_fileZ
date6_listZ
pbase_listrM   dr}   rH   rH   rI   save2bl_list_file  s    
ztimeseries.save2bl_list_file)N)T)T)NNTT)NNNNNN)NN)NN)NNFN)r   )__name__
__module____qualname____doc__rJ   rN   r   ru   rv   rw   r   r   r   r   r   r   r   rH   rH   rH   rI   r      s   

	
 
2
K

&
c                   @   sR   e Zd ZdZdddZdddZddd	Zd
d Zdd Ze	d ddfddZ
dS )geometryzp Geometry object.

    File structure: https://mintpy.readthedocs.io/en/latest/api/data_structure/#geometry
    Nc                 C   s   || _ d| _d S )Nr  rC   rF   rH   rH   rI   rJ     s    zgeometry.__init__Tc                 C   s<   z*| j   |r(tdtj| j W n   Y nX d S )Nzclose geometry file: {}rL   rT   rH   rH   rI   rN     s    
zgeometry.closec              	      s  |r t d| jtj| j |   |   | j	| j
 | _d| _d| j krXd| _t| jd  fdd  D | _t| j| _d  krd	d  d
 d d  D | _t| j| _z| jd W n   Y nX |  jdd | jD 7  _nd | _W 5 Q R X d S )NrV   FY_FIRSTTrW   c                    s    g | ]}t  | tjr|qS rH   )r   r{   Datasetr]   rM   rH   rI   ra     s      z!geometry.open.<locals>.<listcomp>r)   c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra     s     r   c                 S   s   g | ]}d | qS )zbperp-rH   r^   r   rH   rH   rI   ra     s     )rO   rP   rE   rQ   rR   rS   rD   ru   rv   rx   ry   rz   Zgeocodedr   r   r{   r|   datasetNameslistr   r   r   r   removerT   rH   r  rI   r     s(    zgeometry.openc              	   C   st   t | jdT}dd | D d }|| j}t|dkrR|dd \| _| _n|\| _| _W 5 Q R X | j| jfS )NrW   c                 S   s   g | ]}|t kr|qS rH   )geometryDatasetNamesr]   rH   rH   rI   ra     s      z%geometry.get_size.<locals>.<listcomp>r   r   ro   )r{   r|   rD   r   r   r   rx   ry   )rG   rM   dsNameZdsShaperH   rH   rI   rv     s    
zgeometry.get_sizec              	   C   sl   t | jd}t|j| _W 5 Q R X | j D ]4\}}z|d| j|< W q0   || j|< Y q0X q0| jS )NrW   r   )r{   r|   rD   r   r   r   r   r   )rG   rM   r   r   rH   rH   rI   ru     s    zgeometry.get_metadatar   c           	   	      s  | j dd |dkr$dd| j| jf}|dkr6td }nt|trF|g}t| jd:}|d 	dd  |  }|rt
d | j t|jdkr|dd }nt|jd	kr||d |d
 |d |d	 f }ntj|jd tjd} fdd|D }tdd |D r"d|dd< n|D ]}d|| j|< q&|dd|d |d
 |d |d	 f | }tdd |jD rt|}W 5 Q R X |S )ax  Read 2D / 3D dataset with bounding box in space
        Parameters: datasetName : (list of) string, to point to specific 2D dataset, e.g.:
                        height
                        incidenceAngle
                        bperp
                        ...
                        bperp-20161020
                        bperp-20161026
                        bperp-...
                    box : tuple of 4 int, for (x0,y0,x1,y1)
                    print_msg : bool
        Returns: data : 2D or 3D array
        Example:
            obj = geometry('./inputs/geometryRadar.h5')
            obj.read(datasetName='height')
            obj.read(datasetName='incidenceAngle')
            obj.read(datasetName='bperp')
            obj.read(datasetName='bperp-20161020')
            obj.read(datasetName=['bperp-20161020',
                                  'bperp-20161026'])
        Fr   Nr   rW   r   z%reading {:<15} data from file: {} ...ro   r   r   rm   c                    s    g | ]}|  d  dd qS r   r   r   r]   Z
familyNamerH   rI   ra   5  s     z!geometry.read.<locals>.<listcomp>c                 s   s   | ]}| V  qd S NrH   r]   rH   rH   rI   re   6  s     z geometry.read.<locals>.<genexpr>Tc                 s   s   | ]}|d kV  qdS r   rH   r]   rH   rH   rI   re   A  s     )r   ry   rx   r
  r   r   r{   r|   rD   splitrO   rP   r   r   r   r   r   r   r   r   r   )	rG   r   r   rU   rM   r   r   r   r   rH   r  rI   r   	  sD    

&  zgeometry.read)N)T)T)r   r   r   r  rJ   rN   r   rv   ru   r
  r   rH   rH   rH   rI   r    s   




r  c                   @   s   e Zd ZdZd4ddZd5ddZd6dd	Zd
d Zd7ddZdd Z	d8ddZ
d9ddZd:ddZ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@d(d)ZdAd*d+Zed,d- ZedBd.d/ZdCd0d1Zd2d3 ZdS )DifgramStackz Interferograms Stack object.

    File structure: https://mintpy.readthedocs.io/en/latest/api/data_structure/#ifgramstack
    Nc                 C   s   || _ d| _d S )Nr  rC   rF   rH   rH   rI   rJ   O  s    zifgramStack.__init__Tc                 C   s@   z.| j   |r,td| jtj| j W n   Y nX d S )Nzclose {} file: {})	rM   rN   rO   rP   rE   rQ   rR   rS   rD   rT   rH   rH   rI   rN   S  s    
 zifgramStack.closec              	      s  |r t djtjj     	  j
j _dd tjjD _tjdd jj D tjd_tjdnd dd _d	 dd _fd
d D fddtD _ jdd D 7  _W 5 Q R X g _jD ]$  j fddjD 7  _qjdd_ t!j _"z$t#j$d _%t#j$d _&W n   d_%d_&Y nX z$t'j$d _(t'j$d _)W n   d_(d_)Y nX dS )z
        Time format/rules:
            All datetime.datetime objects named with time
            All string in YYYYMMDD        named with date (following roipac)
        rV   c                 S   s   g | ]\}}d  ||qS {}_{}rP   r^   r_   jrH   rH   rI   ra   i  s     z$ifgramStack.open.<locals>.<listcomp>c                 S   s   g | ]}|j |jd   qS rj   rk   r]   rH   rH   rI   ra   j  s   rm   rW   
dropIfgramNr)   c                    s>   g | ]6}t  | tjr | jd d jjfkr|qS )N)r   r{   r  r   rx   ry   r]   )rM   rG   rH   rI   ra   s  s    c                    s   g | ]}| kr|qS rH   rH   r]   )dsNamesrH   rI   ra   v  s      c                 S   s   g | ]}|t kr|qS rH   )ifgramDatasetNamesr]   rH   rH   rI   ra   w  s      c                    s   g | ]}d   |qS rt   r  r]   )r  rH   rI   ra   |  s     Fr  REF_YZREF_XREF_LATREF_LON)*rO   rP   rE   rQ   rR   rS   rD   ru   rv   read_datetimesrx   ry   rz   r   mDatessDates
date12Listr   r   sTimesmTimesr   tbaseIfgramr{   r|   r  pbaseIfgramr   r  r  r   rw   r   r   r   r   r   refYrefXr   ZrefLatZrefLonrT   rH   )r  r  rM   rG   rI   r   [  sF    

"
"zifgramStack.openc              	   C   s   t | jd&}t|j| _|d d d   }W 5 Q R X | j D ]4\}}z|d| j|< W qD   || j|< Y qDX qDt	dd |D }|d | jd< |d | jd	< | jS )
NrW   r   r   c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra     s     z,ifgramStack.get_metadata.<locals>.<listcomp>r   r   r   r   )
r{   r|   rD   r   r   r   flattenr   r   sortedr   rH   rH   rI   ru     s    zifgramStack.get_metadataFc              	      sz   t | jdV |d kr. fdddD d } | j\| _| _| _|r`t d d d  | _W 5 Q R X | j| j| jfS )NrW   c                    s   g | ]}|   kr|qS rH   r   r]   r  rH   rI   ra     s      z(ifgramStack.get_size.<locals>.<listcomp>)r*   r1   r/   r   r  )	r{   r|   rD   r   	numIfgramrx   ry   r   sum)rG   r  r   rH   r  rI   rv     s    "zifgramStack.get_sizec              	      s   t  jd}|d dd }W 5 Q R X t|d  _tdd |dddf D  _tdd |ddd	f D  _	t fd
d jD  _
t fdd j	D  _dS )z4Read date1/2 into array of datetime.datetime objectsrW   r   N)r   r   c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra     s     z.ifgramStack.read_datetimes.<locals>.<listcomp>r   c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra     s     ro   c                    s   g | ]}t j| jqS rH   rX   r]   r`   rH   rI   ra     s     c                    s   g | ]}t j| jqS rH   rX   r]   r`   rH   rI   ra     s     )r{   r|   rD   r   r   r\   r   r   r  r   r#  r"  )rG   rM   r   rH   r`   rI   r    s    ""zifgramStack.read_datetimesr*   c              	      sb  | j dd | jdd}|dkr(dg}nt|tr8|g}t| jd}|d dd  |  }|rztd	 | j t
j| jt
jd	} fd
d|D }tdd |D r|r|d dd }qd|dd< n|D ]}	d|||	< q|dkrdd| j| jf}|dd|d |d |d |d f | }
tdd |
jD rTt
|
}
W 5 Q R X |
S )aH  Read 3D dataset with bounding box in space
        Parameters: datasetName : string, to point to specific 2D dataset, e.g.:
                        unwrapPhase
                        coherence
                        connectComponent
                        ...
                        unwrapPhase-20161020_20161026
                        unwrapPhase-...
                        coherence-20161020_20161026
                        ...
                        ['unwrapPhase-20161020_20161026',
                         'unwrapPhase-20161020_20161101',
                         ...]
                    box : tuple of 4 int, for (x0,y0,x1,y1)
                    print_msg : bool
        Returns: data : 2D or 3D array
        Example:
            obj = ifgramStack('./inputs/ifgramStack.h5')
            obj.read(datasetName='unwrapPhase')
            obj.read(datasetName='coherence')
            obj.read(datasetName='unwrapPhase-20161020_20161026')
            obj.read(datasetName=['unwrapPhase-20161020_20161026',
                                  'unwrapPhase-20161020_20161101'])
        Fr  Nr*   rW   r   r   r   rm   c                    s    g | ]}|  d  dd qS r  r   r]   r  rH   rI   ra     s     z$ifgramStack.read.<locals>.<listcomp>c                 s   s   | ]}| V  qd S r  rH   r]   rH   rH   rI   re     s     z#ifgramStack.read.<locals>.<genexpr>r  Tro   r   r   c                 s   s   | ]}|d kV  qdS r   rH   r]   rH   rH   rI   re     s     )rv   get_date12_listr   r   r{   r|   rD   r  rO   rP   r   r   r+  r   r   r   ry   rx   r   r   )rG   r   r   rU   r  r!  rM   r   r   r   r   rH   r  rI   r     sB    

  zifgramStack.readr+   c              	   C   s  |dkrd}|r$t d|| j nt d|| j |rdtj|rdt d|  t|j|d}nd}t	| jd}|| }	|	j
d }
tj|
tjd	}tj|
d
}t|
D ]}|j|d d|d |
d |	||d |d |d |d f }|rtj||t|k< |dkr(tj||dk< |dk	rJd|||k< d|||k< |r`t|||< qt|||< q|  W 5 Q R X || jfS )z Calculate the spatial average.Nr+   z/calculating spatial median of {} in file {} ...z-calculating spatial mean of {} in file {} ...r   r   rW   r   rm   r   ro   r   r   r   r   )rO   rP   rD   rQ   rR   r   r   r   r{   r|   r   r   r   r   r   r   r   r   r   r   	nanmedianr   rN   r!  )rG   r   r   r   Z	useMedianr   r   r9   rM   dsetr+  r   r   r_   r   rH   rH   rI   r      s:    
&

zifgramStack.spatial_averagec              	   C   s   t | jd6}|d d d  }|r@||d d d  d d f }W 5 Q R X tdd |d d df D }tdd |d d df D }d	d t||D }|S )
NrW   r   r  c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra   8  s     z/ifgramStack.get_date12_list.<locals>.<listcomp>r   c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra   9  s     ro   c                 S   s   g | ]\}}d  ||qS r  r  r  rH   rH   rI   ra   :  s     r{   r|   rD   r   r   r   )rG   r  rM   r   r  r   r!  rH   rH   rI   r-  3  s    &  zifgramStack.get_date12_listc              	   C   s   t | jd4}|d d d  }||d d d   d d f }W 5 Q R X tdd |d d df D }tdd |d d df D }d	d t||D }|S )
NrW   r   r  c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra   A  s     z4ifgramStack.get_drop_date12_list.<locals>.<listcomp>r   c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra   B  s     ro   c                 S   s   g | ]\}}d  ||qS r  r  r  rH   rH   rI   ra   C  s     r0  )rG   rM   r   r  r   r!  rH   rH   rI   get_drop_date12_list=  s    (  z ifgramStack.get_drop_date12_listc              	   C   s   t | jd6}|d d d  }|r@||d d d  d d f }W 5 Q R X dd |d d df D }dd |d d df D }ttt|| }|S )	NrW   r   r  c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra   K  s     z-ifgramStack.get_date_list.<locals>.<listcomp>r   c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra   L  s     ro   )r{   r|   rD   r)  r  set)rG   r  rM   r   r  r   r   rH   rH   rI   rw   F  s    &zifgramStack.get_date_listc                 C   s   | j dd |r4t| j|dd tj}td nXd| j krLtdn@td	| j
| j| | j|| j| j
| jd	 | j
d	 f|dd
}|S )a_  Get reference value
        Parameters: unwDatasetName : string, unwrapPhase, or unwrapPhase_unwCor
                    skip_reference : bool, skip reference value (for simulation only)
                    dropIfgram : bool, skip ifgrams marked as dropped or not
        Returns:    ref_phase : 1D np.array in size of (num_ifgram,) in float32
        Fr   r  r   zIskip checking reference pixel info - This is for offset and testing ONLY.r  zCNo REF_X/Y found!
run reference_point.py to select reference pixel.z1reference pixel in y/x: ({}, {}) from dataset: {}ro   )r   r   r  rU   )r   r   r   rv   r   rO   r   r   
ValueErrorrP   r&  r'  r   )rG   ZunwDatasetNameZskip_referencer  	ref_phaserH   rH   rI   get_reference_phaseP  s    

zifgramStack.get_reference_phasec              	      s&  | j dd t| jd  |dkr< fdddD d }td	|  | }tj|jd
d tj	d}tj|jd tj	d}|r| j
}t|}t|d }tj|d}	t|D ]V}
|	j|
d
 d|
d
 |d |||
 ddddf }d||dk< d|t|< q|	  W 5 Q R X |S )z|Return the common mask of pixels with non-zero value in dataset of all ifgrams.
           Ignoring dropped ifgrams
        Fr   rW   Nc                    s   g | ]}|   kr|qS rH   r*  r]   r  rH   rI   ra   l  s    z,ifgramStack.nonzero_mask.<locals>.<listcomp>)r,   r*   r   z:calculate the common mask of pixels with non-zero {} valuero   r   rm   r   r   r           )r   r{   r|   rD   rO   rP   r   onesr   r   r  r,  wherer   r   r   r   isnanrN   )rG   r   rU   r  r/  r9   ZdropIfgramFlagZnum2readZidx2readr   r_   r   rH   r  rI   nonzero_maske  s,    
zifgramStack.nonzero_mask   c              
   C   s  | j dd |d krd}td|| j tj| jtjd}|r\| j}t	|dkr\t
dd|krd	t| jd
  dtj  }tj| jtjdd }|| }t| jd }|| }d }	d|kr6| jd k	r6d| j  kr| jkr6n nF| jd k	r6d| j  kr| jkr6n n|d d | j| jf | }	tj|tjd| j | j d }
tt|
d |d  }tt| j| d d }tt| j| }tj|jdd tjd}tj |d}t!|D ]}|| }t"|| | j}|j#|d d|| jd |d d ||d d f | }d|kr|	d k	rd|t$|	%d	ddd|jd |jd f8 }t!|jd D ],}||d d d d f  |||  9  < qrtj&|dd|||d d f< q|'  W 5 Q R X |S )NFr   r+   z3calculate the temporal average of {} in file {} ...rm   r6  zMALL interferograms are marked as dropped, can not calculate temporal average.r*   r   Z
WAVELENGTHg      @rp   rW   r   r;  r      @
   ro   r   zlines {}/{}r   r   r   )(r   rO   rP   rD   r   r7  r+  r   r  r   	Exceptionr   r   pir   r$  r   r{   r|   r&  ry   r'  rx   r,  r   r   ceilrintr   r   r   r   r   r   minr   tiler   r   rN   )rG   r   r  
max_memoryZifgram_flagZphase2ranger   rM   r/  Zref_valds_sizeZnum_stepZrow_stepr   r   r_   Zr0Zr1r   r  rH   rH   rI   r     sf    
  
 

,*"zifgramStack.temporal_averagec                 C   s   |   }| j|ddd }tj|jd tjd}t|jd D ]<}||d d f }t|dkd t|dkd  ||< q>t|S )Nr   )refDaterm   ro   r   )	r-  get_design_matrix4timeseriesr   r   r   r   r   r8  max)rG   date12_listAZnum_connr_   ZAirH   rH   rI   get_max_connection_number  s    *z%ifgramStack.get_max_connection_numberc                 C   s   | j dd | j}| j}|s,| jd | j }|| | d }tt|d |d  }tt|| d d }tt|| }|r|dkrtd	|  td
||f  td|  g }	t	|D ]2}
|
| }t
||| g}d|||f}|	| q|	|fS )a  Split into chunks in rows to reduce memory usage.

        Parameters: max_memory - float, max memory to use in GB
                    dim0_size  - the 1st dimension size of all used datasets
                                 e.g., dim0_size = num_pair * 2 + num_date
                    print_msg  - bool
        Returns:    box_list   - list of tuple of 4 int
                    num_box    - int, number of boxes
        Fr   r   r;  g      ?r<  r=  ro   zmaximum memory size: %.1E GBz-split %d lines into %d patches for processingz"    with each patch up to %d linesr   )r   rx   ry   r+  r   r   r   r@  rO   r   rB  append)rG   rD  Z	dim0_sizerU   rx   ry   rE  Znum_boxy_stepZbox_listr_   Zy0y1r   rH   rH   rI   split2boxes  s(    
zifgramStack.split2boxesc           	   
      s   | j dd | j|d}t|}g }t|| D ]}g }t|D ]*}|d|||  ||| d   q@|d|| |||   t fdd|D r0| fdd|D  q0tj|tj	d	}tj
|d
d}|S )a  Get the indices of interferograms that forms the given connection level closure loop.

        Parameters: conn       - int, connection level
                    dropIfgram - bool, exclude the dropped interferograms.
        Returns:    cp_idx     - 2D np.ndarray in int16 in size of (num_cp, conn + 1)
                                 Each row for the indices of interferograms for one closure loop.
                                 num_cp <= num_date - conn
        Fr  r  ro   c                 3   s   | ]}| kV  qd S r  rH   r^   xrI  rH   rI   re   	  s     z6ifgramStack.get_closure_phase_index.<locals>.<genexpr>c                    s   g | ]}  |qS rH   r   rP  rR  rH   rI   ra   
  s     z7ifgramStack.get_closure_phase_index.<locals>.<listcomp>rm   r   r   )r-  rw   r   r   rL  rP   r   r   r   r   unique)	rG   connr  r   r   cp_idxr_   Zcp_date12_listr  rH   rR  rI   get_closure_phase_index  s    	(z#ifgramStack.get_closure_phase_indexc                 C   s  t | jdd}|d |d  }|d |d  }| j|dd}|jd }td||   td	|  |s||| k rd
| d||  d}	|	d7 }	t|	n|dk rtd| d| j|dd}
| jdd}t|
jd D ](}|
| dk}|
| |  || 8  < qt	j
|||ft	jd}t|D ]P}||ddf ||df  }}t	j|
| dd|
|  }t	d| ||< q(|sd}nD|dkrt	j|dd}n*|dkrt	j|dd}ntd| dt	|||fS )a  Computes wrapped sequential closure phases for a given conneciton level.

        Reference: Equation (21) in Zheng et al. (2022, TGRS)
        For conn = 5, seq_closure_phase = p12 + p23 + p34 + p45 + p56 - p16.

        Parameters: box       - tuple of 4 int, bounding box in (x0, y0, x1, y1)
                    conn      - int, connection level of the closure phase
                    post_proc - str, post processing of the closure phase:
                                None - 3D array in float32, seq closure phase
                                sum  - 2D array in complex64, sum  in time of the complex seq closure phase
                                mean - 2D array in complex64, mean in time of the complex seq closure phase
        Returns:    cp_w      - 3D np.ndarray in float32 in size of (num_cp, box_len, box_wid)
                                wrapped sequential  closure phase for the given connection level.
                    sum_cp    - None or 2D np.ndarray in complex64 in size of (box_len, box_width)
                                wrapped average seq closure phase for the given connection level,
                                controlled by post_proc.
                    num_cp    - int, number of  seq closure phase for the given connection level.
        Tr  r   r   r   ro   )rU  r  z)number of closure measurements expected: z)number of closure measurements found   : znum_cp (z) < num_date - conn ()z% --> some interferograms are missing!z'No triplets found at connection level: !F)r   rU   r6  rm   Nr   r   y              ?r,  meanzun-recognized post_proc=z! Available choices: sum, mean.)r   rw   rW  r   rO   r>  r   r5  r   r   r   r   r,  exprZ  r3  angle)rG   r   rU  Z	post_procr   Zbox_widZbox_lenrV  Znum_cpmsgZphaser4  r_   r9   Zcp_wZidx_plusZ	idx_minorZcp0_wZsum_cprH   rH   rI   get_sequential_closure_phase  s@    



z(ifgramStack.get_sequential_closure_phasec              	   C   s  t | } dd | D }dd t|D }tttj|}t|d}t|}g }|D ]\}}}	||f}
||	f}||	f}z||
 }|| }|| }W n t	k
r   Y qXY nX t
j|t
jd}d||< d||< d||< || qXt|d	krtd
|  dS t
|t
jS )a  Generate the design matrix of ifgram triangle for unwrap error correction using phase closure

        Parameters: date12_list : list of string in YYYYMMDD_YYYYMMDD format
        Returns:    C : 2D np.array in size of (num_tri, num_ifgram) consisting 0, 1, -1
                        for 3 SAR acquisition in t1, t2 and t3 in time order,
                        ifg1 for (t1, t2) with 1
                        ifg2 for (t1, t3) with -1
                        ifg3 for (t2, t3) with 1
        Examples:   obj = ifgramStack('./inputs/ifgramStack.h5')
                    date12_list = obj.get_date12_list(dropIfgram=True)
                    C = ifgramStack.get_design_matrix4triplet(date12_list)
        c                 S   s   g | ]}t |d qS )_)tupler  r  rH   rH   rI   ra   n  s     z9ifgramStack.get_design_matrix4triplet.<locals>.<listcomp>c                 S   s   i | ]\}}||qS rH   rH   )r^   idxZifgrH   rH   rI   
<dictcomp>q  s      z9ifgramStack.get_design_matrix4triplet.<locals>.<dictcomp>r   rm   ro   r   r   z9
WARNING: No triangles found from input date12_list:
{}!
N)r  	enumerater)  r2  	itertoolschainfrom_iterablecombinationsr   KeyErrorr   r   int8rL  rO   rP   stackastyper   )rI  Zdate12_tuplesZ
ifg_to_idxr   Zclosure_listMZC_listZdate1Zdate2Zdate3Zifg12Zifg23Zifg13Zidx12Zidx23Zidx13rowrH   rH   rI   get_design_matrix4triplet]  s4    
z%ifgramStack.get_design_matrix4tripletc                    s  t | } dd | D }dd | D }tt t|| t| }t}td  t fddD }dd ||d  D }tj|tjdd }t	||ftj}t	||ftj}	t
|D ]}
fd	d| |
 d
D \}}d||
|f< d||
|f< ||k r8||d |d  |||  |	|
||f< q||| ||d |d   |	|
||f< q|dkr|dkrtt|dkr|d }nd }|r|}t|ddd|f |dd|d df f}|	ddddf }	||	fS )a  Return design matrix of the input ifgramStack for timeseries estimation

        Parameters: date12_list - list of string in YYYYMMDD_YYYYMMDD format
                    refDate     - str, date in YYYYMMDD format
                                  set to None for the 1st date
                                  set to 'no' to disable reference date
        Returns:    A - 2D array of float32 in size of (num_ifgram, num_date-1)
                    B - 2D array of float32 in size of (num_ifgram, num_date-1)
        Examples:   obj = ifgramStack('./inputs/ifgramStack.h5')
                    A, B = obj.get_design_matrix4timeseries(obj.get_date12_list(dropIfgram=True))
                    A = ifgramStack.get_design_matrix4timeseries(date12_list, refDate='20101022')[0]
                    A = ifgramStack.get_design_matrix4timeseries(date12_list, refDate=0)[0] #do not omit the 1st column
        c                 S   s   g | ]}| d d qS )r_  r   r  r]   rH   rH   rI   ra     s     z<ifgramStack.get_design_matrix4timeseries.<locals>.<listcomp>c                 S   s   g | ]}| d d qS )r_  ro   ro  r]   rH   rH   rI   ra     s     r   c                    s   g | ]}t j| qS rH   )rY   rZ   r[   r]   )date_formatrH   rI   ra     s     c                 S   s   g | ]}|j |jd   qS rj   rk   r]   rH   rH   rI   ra     s     rm   rp   c                    s   g | ]}  |qS rH   rS  r  )r   rH   rI   ra     s     r_  r   ro   noN)r  r)  r2  r   r   r   r   r   r   r   r   r  r   r   )rI  rF  Zdate1sZdate2sZ
num_ifgramr   r   r   rJ  Br_   ind1ind2Zind_rrH   )rp  r   rI   rG    s:     
..



2z(ifgramStack.get_design_matrix4timeseriesc              	   C   s   t | jd.}|d dd }|r8||d dd  }W 5 Q R X | j|d}| |d }tj|jd d tjd}tj	j
||dd	d |dd< |S )
z[Get spatial perpendicular baseline in timeseries from ifgramStack, ignoring dropped ifgramsrW   r)   Nr  r  r   ro   rm   )rcond)r{   r|   rD   r-  rG  r   r   r   r   linalglstsq)rG   r  rM   r%  r!  rJ  ZpbaseTimeseriesrH   rH   rI   get_perp_baseline_timeseries  s    z(ifgramStack.get_perp_baseline_timeseriesc              	      s    dkrdS | j dd}| j dd}ttt|t| }| krPtd dS t| jd}td| j td t	j
 fd	d
|D t	jd|d dd< tD ]>}|| krtd| tt || jd< td qW 5 Q R X dS )z8Update dropIfgram dataset based on input date12List2DropNFr  Tz^The same date12List2Drop / dropIfgram is already marked in the file, skip updating dropIfgram.zr+zopen file {} with r+ modez"update HDF5 dataset "/dropIfgram".c                    s   g | ]}| kqS rH   rH   r]   date12List2DroprH   rI   ra     s     z2ifgramStack.update_drop_ifgram.<locals>.<listcomp>rm   r  z.update MODIFICATION_TIME in HDF5 dataset "/{}"ZMODIFICATION_TIMEro   )r-  r)  r  r2  rO   r{   r|   rD   rP   r   r   r   r  r   r   timer   sleep)rG   rz  Zdate12ListAllZdate12ListKeptOldZdate12List2DropOldrM   r  rH   ry  rI   update_drop_ifgram  s"    *zifgramStack.update_drop_ifgram)N)T)T)FN)r*   NTF)r+   NNFFN)T)F)r*   FF)NTT)r+   Tr;  )r;  NT)T)N)N)T)r   r   r   r  rJ   rN   r   ru   rv   r  r   r   r-  r1  rw   r5  r:  r   rK  rO  rW  r^  staticmethodrn  rG  rx  r}  rH   rH   rH   rI   r  I  s8   


5

A    
3

	




>

(
!
J
8?
r  c                   @   s    e Zd ZdddZdddZdS )r   Nc                 C   s
   || _ d S r  )rD   rF   rH   rH   rI   rJ     s    zsingleDataset.__init__c              	   C   sj   t | jd&}t| d }|| d d  }W 5 Q R X |d k	rf||d |d |d |d f }|S )NrW   r   ro   r   r   )r{   r|   rD   r  r   )rG   r   rM   r  r   rH   rH   rI   r     s     zsingleDataset.read)N)N)r   r   r   rJ   r   rH   rH   rH   rI   r     s   
r   c                   @   sH   e Zd ZdZdddZdddZddd	Zd
d Zdd ZdddZ	dS )r   a3  
    Time-series object in HDF-EOS5 format for Univ of Miami's InSAR Time-series Web Viewer
        Link: http://insarmaps.miami.edu
    It contains a "timeseries" group and three datasets: date, bperp and timeseries.

    File structure: https://mintpy.readthedocs.io/en/latest/hdfeos5/#file_structure
    Nc                 C   s<   || _ d| _ddddddddddddddddddd| _d S )Nr   Zobservationqualityr  )r   r   r   r   r   r   r8   r9   r+   varianceZuncertaintyr   r#   r%   r$   r&   r'   r)   )rD   rE   datasetGroupNameDictrF   rH   rH   rI   rJ     s*    zHDFEOS.__init__Tc                 C   s<   z*| j   |r(tdtj| j W n   Y nX d S rK   rL   rT   rH   rH   rI   rN   3  s    
zHDFEOS.closec              	      s&  |r t d| jtj| j |   t| j	d | _
t| j	d | _g | _t| jd}d |  }dd |d d d  D | _|d	 d d  | _t| j| _|  j fd
d| jD 7  _dD ]P |  }| D ]:}t|| tjrt|| jdkr| jd | qqW 5 Q R X d S )NrV   LENGTHWIDTHrW   #HDFEOS/GRIDS/timeseries/observationc                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra   F  s     zHDFEOS.open.<locals>.<listcomp>r   r)   c                    s   g | ]}d   |qS )z{}/displacement-{}r  r]   gnamerH   rI   ra   K  s     )zHDFEOS/GRIDS/timeseries/qualityz HDFEOS/GRIDS/timeseries/geometryr   r   )rO   rP   rE   rQ   rR   rS   rD   ru   r   r   rx   ry   r   r{   r|   r   r}   r   r   r   r   r  r   rL  )rG   rU   rM   gr   rH   r  rI   r   ;  s$    "zHDFEOS.openc              	   C   s   t | jd"}t|j| _|d d d  }W 5 Q R X | j D ]4\}}z|d| j|< W q@   || j|< Y q@X q@| j| jd< dd |D }d| j	 kr|d | jd< |
| jd | _| jS )	NrW   z(HDFEOS/GRIDS/timeseries/observation/dater   r   c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra   _  s     z'HDFEOS.get_metadata.<locals>.<listcomp>r   r   )r{   r|   rD   r   r   r   r   r   rE   r   r   r~   r   rH   rH   rI   ru   S  s    zHDFEOS.get_metadatac              	   C   sD   t | jd*}|d }dd |d d d  D | _W 5 Q R X | jS )NrW   r  c                 S   s   g | ]}| d qS r   r   r]   rH   rH   rI   ra   h  s     z(HDFEOS.get_date_list.<locals>.<listcomp>r   r   )rG   rM   r  rH   rH   rI   rw   e  s    &zHDFEOS.get_date_listc           
   	      s  | j dd |dkr$dd| j| jg}|dkr8td g}nt|trH|g}t| jdL}|d 	dd  | j
  }|d|  }|rtd	 | j t|jd
kr|dd }nt|jdkr||d
 |d |d |d f }ntj|jd tjd} fdd|D }tdd |D r6d|dd< n|D ]}	d|| j|	< q:|dd|d
 |d |d |d f | }tdd |jD rt|}W 5 Q R X |S )a  Read dataset from HDF-EOS5 file
        Parameters: self : HDFEOS object
                    datasetName : (list of) str
                    box : tuple of 4 int, for (x0, y0, x1, y1)
                    print_msg : bool
        Returns:    data: 2D or 3D array
        Example:    obj = HDFEOS('S1_IW1_128_0593_0597_20141213_20171221.he5')
                    obj.read(datasetName='displacement')
                    obj.read(datasetName='displacement-20150915')
                    obj.read(datasetName=['displacement-20150915',
                                          'displacement-20150921'])
                    obj.read(datasetName='incidenceAngle')
        Fr   Nr   r   rW   r   zHDFEOS/GRIDS/timeseries/{}/{}r   ro   r   r   rm   c                    s    g | ]}|  d  dd qS r  r   r]   r  rH   rI   ra     s     zHDFEOS.read.<locals>.<listcomp>c                 s   s   | ]}| V  qd S r  rH   r]   rH   rH   rI   re     s     zHDFEOS.read.<locals>.<genexpr>Tc                 s   s   | ]}|d kV  qdS r   rH   r]   rH   rH   rI   re     s     )r   ry   rx   r   r   r   r{   r|   rD   r  r  rP   rO   r   r   r   r   r   r   r   r   r   )
rG   r   r   rU   rM   Z	groupNamer   r   r   r   rH   r  rI   r   k  sF    

&  zHDFEOS.read)N)T)T)NNT)
r   r   r   r  rJ   rN   r   ru   rw   r   rH   rH   rH   rI   r     s   


)rQ   r{  rd  rZ   rY   r{   numpyr   mintpy.utilsr   r   r   r   r
   r   r   r   r   r   ZdataTypeDictZtimeseriesKeyNamesr   r
  r  ZdatasetUnitDictr   r  r  r   r   rH   rH   rH   rI   <module>   s                

E  9     ?