B
    Qa*              
   @   sp  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 d dl	m
Z
mZ d dlmZ d dlmZ d dlmZmZmZmZmZ dZdd	d
ddddgZdZedZdZdd ZdBddZdd Zdd Z dCddZ!dDd d!Z"d"d# Z#dEd$d%Z$dFd'd(Z%dGd*d+Z&dHd-d.Z'dId0d1Z(dJd2d3Z)dKd5d6Z*d7d8 Z+dLd:d;Z,dMd<d=Z-dNd>d?Z.e/d@krle.ej0dAd  dS )O    N)linalg)ifgramStackcluster)decorrelation)get_template_content)readfile	writefileptimeutils	arg_groupzmintpy.networkInversion.obsDatasetName	numIfgram
weightFuncmaskDatasetmaskThresholdminRedundancyminNormVelocitya  example:
  ifgram_inversion.py inputs/ifgramStack.h5 -t smallbaselineApp.cfg --update
  ifgram_inversion.py inputs/ifgramStack.h5 -w no  # turn off weight for fast processing
  ifgram_inversion.py inputs/ifgramStack.h5 -c no  # turn off parallel processing
  # offset
  ifgram_inversion.py inputs/ifgramStack.h5 -i rangeOffset   -w no -m waterMask.h5 --md offsetSNR --mt 5
  ifgram_inversion.py inputs/ifgramStack.h5 -i azimuthOffset -w no -m waterMask.h5 --md offsetSNR --mt 5
invert_networku  references:
  Berardino, P., Fornaro, G., Lanari, R., & Sansosti, E. (2002). A new algorithm for surface
    deformation monitoring based on small baseline differential SAR interferograms. IEEE TGRS,
    40(11), 2375-2383. doi:10.1109/TGRS.2002.803792
  Pepe, A., and Lanari, R. (2006), On the extension of the minimum cost flow algorithm for phase unwrapping
    of multitemporal differential SAR interferograms, IEEE-TGRS, 44(9), 2374-2383.
  Perissin, D., and Wang, T. (2012), Repeat-pass SAR interferometry with partially coherent targets, IEEE TGRS,
    50(1), 271-280, doi:10.1109/tgrs.2011.2160644.
  Samiei-Esfahany, S., Martins, J. E., Van Leijen, F., and Hanssen, R. F. (2016), Phase Estimation for Distributed
    Scatterers in InSAR Stacks Using Integer Least Squares Estimation, IEEE TGRS, 54(10), 5671-5687.
  Seymour, M. S., and Cumming, I. G. (1994), Maximum likelihood estimation for SAR interferometry, 1994.
    IGARSS '94., 8-12 Aug 1994.
  Yunjun, Z., Fattahi, H., and Amelung, F. (2019), Small baseline InSAR time series analysis: Unwrapping error
    correction and noise reduction, Computers & Geosciences, 133, 104331, doi:10.1016/j.cageo.2019.104331.
  Yunjun, Z., Fattahi, H., Brancato, V., Rosen, P., Simons, M. (2021), Oral: Tectonic displacement mapping from SAR
    offset time series: noise reduction and uncertainty quantification, ID 590, FRINGE 2021, 31 May – 4 Jun, 2021, Virtual.
c           
   C   s  t jdt jtd t d t d} | jddd | jddd	d
d | jddddtdd | jddddd | jddddddd | jdddd | jd d!d"d#d$d% | d&d'}|jd(d)d*d+d+d,d-d.hd/d0 |jd1d2d3d4d% |jd5d6d7d8d7gd9d0 | jd:d;d<d#d=d% | d>d?}|jd@dAdBdCdDd |jdEdFdGdHdIt	dJdKdL |jdMdNdOdPdIt	dQdRdL t
| } t
| } | jdSdTd#dUd% | S )VNz2Invert network of interferograms into time-series.
)descriptionformatter_classepilogifgramStackFilez(interferograms stack file to be inverted)helpz-tz
--templatetemplateFileztemplate text file with options)destr   z-iz-dz--dsetr   zkdataset name of unwrap phase / offset to be used for inversion
e.g.: unwrapPhase, unwrapPhase_bridging, ...)r   typer   z-mz--water-maskwaterMaskFilez4Skip inversion on the masked out region, i.e. water.z-oz--outputoutfile   )ZTS_FILEZ	TCOH_FILEZNUM_INV_FILEz)Output file name. (default: %(default)s).)r   nargsmetavarr   z
--ref-dateref_datez&Reference date, first date by default.z--skip-referencez
--skip-refskip_ref
store_truez:[for offset and testing] do not apply spatial referencing.)r   actionr   solverz(solver for the network inversion problemz-wz--weight-funcr   varZfimcohnozfunction used to convert coherence to weight for inversion:
var - inverse of phase variance due to temporal decorrelation (default)
fim - Fisher Information Matrix as weightcoh - spatial coherence
no  - no/uniform weight)r   defaultchoicesr   z--min-norm-phaser   store_falsezoEnable inversion with minimum-norm deformation phase, instead of the default minimum-norm deformation velocity.z--normresidualNormL2L1z;Optimization mehtod, L1 or L2 norm. (default: %(default)s).z--stdz
--calc-stdcalcStdzdCalculate time-series STD via linear propagation from the network of interferograms or offset pairs.maskz&mask observation data before inversionz--mask-dsetz--mask-datasetz--mdr   zBdataset used to mask unwrapPhase, e.g. coherence, connectComponentz--mask-thresz--mask-thresholdz--mtr   NUMg?zIthreshold to generate mask when mask is coherence (default: %(default)s).)r   r!   r   r*   r   z--min-redunz--min-redundancyz--mrr   g      ?zWminimum redundancy of interferograms for every SAR acquisition. (default: %(default)s).z--updateupdate_modezEnable update mode, and skip inversion if output timeseries file already exists,
readable and newer than input interferograms file)argparseArgumentParserRawTextHelpFormatter	REFERENCETEMPLATEEXAMPLEadd_argumentstradd_argument_groupfloatr   add_memory_argumentadd_parallel_argument)parserr&   r1    rA   M/home/centos/operations/rsmas_insar/sources/MintPy/mintpy/ifgram_inversion.pycreate_parserC   sJ    





rC   c       
      C   s0  t  }|j| d}t|j}|d dkr<td|d |jrTt|j|\}}nt	 }t
tj|j|j|_|jr|jdkrtd d |_|jrtj|jsd |_|js`d|_dd	d
d}d}|| kr|| r||  dd}| j|| 7  _td| td|j t|j}|jdd |j|jkr`d|j|j}	t|	d|j krd| krd| krd|_|js|jdrdddg|_nd|jdrdddg|_nH|jdrd d!dg|_n,|jd"r
d#d$d%g|_ntd&|j|j\|_|_|_ |S )'N)args	FILE_TYPE)r   z0input is {} file, support ifgramStack file only.1zJWARNING: number of workers is 1, turn OFF parallel processing and continueunwrapPhaseZ	_bridgingZ_phaseClosureZ_bridging_phaseClosure)bridgingphase_closurezbridging+phase_closurezmintpy.unwrapError.method  z3phase unwrapping error correction "{}" is turned ONzuse dataset "{}" by defaultF)	print_msgz-input dataset name "{}" not found in file: {}offsetREF_XREF_YTztimeseries.h5ztemporalCoherence.h5znumInvIfgram.h5azimuthOffsetztimeseriesAz.h5zresidualInvAz.h5znumInvOffset.h5rangeOffsetztimeseriesRg.h5zresidualInvRg.h5ionztimeseriesIon.h5ztemporalCoherenceIon.h5znumInvIon.h5z0un-recognized input observation dataset name: {})!rC   
parse_argsr   read_attributer   
ValueErrorformatr   read_template2inpsdictr;   r   DaskClusterformat_num_worker	numWorkerprintr   ospathisfiler   keyslowerreplacer   opendatasetNamesr#   r   
startswithtsFileinvQualityFile
numInvFile)
iargsr@   inpsatrtemplateZobs_suffix_mapkeyZunw_err_method	stack_objmsgrA   rA   rB   cmd_line_parse   s\    
rp   c                s:  |s
t  }t|}t| tfddt| D }xT|D ]L}t|  }|dkrh|||< qF|rF|dkrt	|||< qF|dkrF|||< qFW d  fddt| D }xX|D ]P} |  }|dkr|||< q|r|d	krt
|||< q|d
krt	|||< qW x dD ]}|| sd||< qW |fS )z/Read input template options into Namespace inpsc                s    g | ]}t |   kr|qS rA   )
key_prefixr`   ).0i)rl   rA   rB   
<listcomp>   s    z&read_template2inps.<locals>.<listcomp>)r   r   r   )r   r   )r-   r   zmintpy.compute.c                s    g | ]} |   kr|qS rA   )r`   )rr   rs   )dask_key_prefixrl   rA   rB   rt      s    )r   config)r[   )	maxMemory)r   r)   )rp   varsr   read_templateutcheck_template_auto_valuelistr`   rq   r=   r;   )template_filerj   iDictkeyListrm   valuerA   )ru   rl   rB   rW      s<    







rW   c          	      s  t d t d d}tdd jD s>d}t dj ntjd d	}|d
 jd }W d Q R X tj	jd }||krd}t djd  nt dj tj
d	(}t|j jdtjj
}W d Q R X tdd jD }||krd}t dj nt dj |dkrtj
 tjttj
jdd_fdddD }tfddtD rd}t dt nB|rt fdd|D rd}t d| nt dt t d| |S )Nz2--------------------------------------------------zupdate mode: ONskipc             s   s   | ]}t j|V  qd S )N)r]   r^   r_   )rr   rs   rA   rA   rB   	<genexpr>   s    zrun_or_skip.<locals>.<genexpr>runz"1) NOT ALL output files found: {}.r   r
timeseries   z'1) output file {} is NOT fully written.z"1) output files already exist: {}.MODIFICATION_TIMEc             s   s   | ]}t j|V  qd S )N)r]   r^   getmtime)rr   rs   rA   rA   rB   r     s    z52) output files are NOT newer than input dataset: {}.z22) output dataset is newer than input dataset: {}.T)
dropIfgramc                s   g | ]}|   kr|qS rA   )r`   )rr   rs   )atr_tsrA   rB   rt     s    zrun_or_skip.<locals>.<listcomp>)rO   rN   c             3   s.   | ]&}t t|  t| d kV  qdS )NoneN)r;   rx   getrq   )rr   rm   )r   rj   rA   rB   r     s    z83) NOT all key configuration parameters are the same: {}c             3   s   | ]}|  | kV  qd S )NrA   )rr   rm   )atr_ifgr   rA   rB   r     s    z(3) NOT all the metadata are the same: {}z53) all key configuration parameters are the same: {}.zrun or skip: {}.)r\   allr   rV   h5pyFilesizer]   r^   getsizer   r=   r   attrsr   r   minr   rT   rf   lenr   get_date12_listr   any
configKeys)rj   flagf	fsize_reffsizetito	meta_keysrA   )r   r   rj   rB   run_or_skip   sD    ,

 r   Th㈵>      ?temporalCoherencec
          	   C   sF  | | jd d}|dk	r,| | jd d}| jd d }
|jd }tj|
|ftjd}|dkrhtj}nd}d}t|| ||gd\}\} }}ttj| dkdd	|k r|||fS |dk	ryt	
t|j| W n t	jk
r   |||fS X y&|r|dk	r2t	jt||t|||d
dd \}}nt	j|||d
dd \}}t|||||||	d}|t|d|f }tj|dd	|ddddf< n~|dk	rt	jt| |t|||d
dd \}}nt	j| ||d
dd \}}t| ||||||	d}||ddddf< W n t	jk
r0   Y nX | jd }|||fS )a  Estimate time-series from a stack/network of interferograms with
    Least Square minimization on deformation phase / velocity.

    Problem: A X = y
    opt 1: X = np.dot(np.dot(numpy.linalg.inv(np.dot(A.T, A)), A.T), y)
    opt 2: X = np.dot(numpy.linalg.pinv(A), y)
    opt 3: X = np.dot(scipy.linalg.pinv(A), y)
    opt 4: X = scipy.linalg.lstsq(A, y)[0] [recommend and used]

    opt 4 supports weight.
    scipy.linalg provides more advanced and slighted faster performance than numpy.linalg.
    This function relies on the LAPACK routine gelsd. It computes the minimum-norm
    solution to a linear least squares problem using the singular value decomposition
    of A and a divide and conquer method.

    opt 4 is faster than opt 1/2/3 because it estimates X directly without calculating
    the A_inv matrix.

    opt 2/3 is better than opt 1 because numpy.linalg.inv() can not handle rank defiency of
    design matrix B

    Traditional Small BAseline Subsets (SBAS) algorithm (Berardino et al., 2002, IEEE-TGRS)
    is equivalent to the setting of:
        min_norm_velocity=True
        weight_sqrt=None

    Parameters: A                 - 2D np.ndarray in size of (num_pair, num_date-1)
                B                 - 2D np.ndarray in size of (num_pair, num_date-1),
                                    design matrix B, each row represents differential temporal
                                    baseline history between reference and secondary date of one interferogram
                y                 - 2D np.ndarray in size of (num_pair, num_pixel),
                                    phase/offset of all interferograms with no-data value: NaN.
                tbase_diff        - 2D np.ndarray in size of (num_date-1, 1),
                                    differential temporal baseline history
                weight_sqrt       - 2D np.ndarray in size of (num_pair, num_pixel),
                                    square root of weight of all interferograms
                min_norm_velocity - bool, assume minimum-norm deformation velocity, or not
                rcond             - cut-off ratio of small singular values of A or B, to maintain robustness.
                                    It's recommend to >= 1e-5 by experience, to generate reasonable result.
                min_redundancy    - float, min redundancy defined as min num_pair for every SAR acquisition
                inv_quality_name  - str, inversion quality type/name
                                    temporalCoherence for phase
                                    residual          for offset
    Returns:    ts                - 2D np.ndarray in size of (num_date, num_pixel), phase time-series
                inv_quality       - 1D np.ndarray in size of (num_pixel), temporal coherence (for phase) or residual (for offset)
                num_inv_obs       - 1D np.ndarray in size of (num_pixel), number of observations (ifgrams / offsets)
                                    used during the inversion
    r   N   )dtyperesidualg        )mat_list)axis)cond   )inv_quality_nameweight_sqrtrL   )reshapeshapenpzerosfloat32nanskip_invalid_obsr   sumr   invdotTLinAlgErrorlstsqmultiplycalc_inv_qualitytilecumsum)ABy
tbase_diffr   min_norm_velocityrcondmin_redundancyr   rL   num_date	num_pixeltsinv_qualitynum_inv_obsXe2Zts_diffrA   rA   rB   estimate_timeseries)  sZ    3




 



r   c             C   s   | | jd d}| | jd d}tj| jd dftjdtj }t|| |gd\}\} }ttj| dkdd|k r||S t	dt
|  }t	t| j|| tj}||||k < t|}|S )	a  Estimate the time-series STD from network of STD via linear propagation.
    Pixel by pixel only.

    For a system of linear equations: A X = y, propagate the STD from y to X.

    Parameters: G      - 2D np.ndarray in size of (num_pair, num_date-1), design matrix
                y      - 2D np.ndarray in size of (num_pair, 1), stack of obs
                y_std  - 2D np.ndarray in size of (num_pair, 1), stack of obs std. dev.
    Returns:    ts_std - 2D np.ndarray in size of (num_date, 1), time-series obs std. dev.
    r   r   r   )r   )r   g        )r   g      ?)r   r   r   r   r   r   r   r   r   diagsquareflattenr   r   r   r   astypesqrt)Gr   y_stdr   r   ts_stdZstack_cov_invZts_varrA   rA   rB   estimate_timeseries_std  s     &
r   c             C   sv   t t | rnt | dddf   }| |ddf } x0t|D ]$\}}|dk	rF||ddf ||< qFW | |fS )a  Skip invalid observations in the stack of phase/offset and update corresponding matrices.
    This applies to the pixel-wised inversion only, because the region-wised inversion has valid obs in all pairs.
    Parameters: obs      - 2D np.ndarray in size of (num_pair, num_pixel),
                           observations (phase / offset) of all interferograms with no-data value: NaN.
                mat_list - list of 2D np.ndarray in size of (num_pair, *) or None
    Returns:    obs / mat_list
    Nr   )r   r   isnanr   	enumerate)obsr   r   rs   matrA   rA   rB   r     s    r   c          	   C   s  |j \}}tj|tjd}	ttd| }
||
krtt||
 }|r^td	||
| xt
|D ]b}||
 }t|d |
 |}|dkr|dd||f t| |dd||f  }ttjtd| dd	| |	||< n|d
kr|dk	rZ|dd||f t| |dd||f  }ttjt|d dd	|	||< n4||| jdkrt||| ntj|	||< tdtt|d }|rj|d | dkrjtd	|d | qjW n|dkr|t| | }ttjtd| dd	| }	nn|d
krr|dk	rT|| | }ttjt|d dd	}	n|jdkrjt|ntj}	ntd| |	S )a  Calculate the inversion quality of the time series estimation.

    Parameters: G                - 2D np.ndarray in size of (num_pair, num_date-1), design matrix A or B
                X                - 2D np.ndarray in size of (num_date-1, num_pixel), solution
                y                - 2D np.ndarray in size of (num_pair, num_pixel), phase or offset
                e2               - 1D np.ndarray in size of (num_pixel,), square of the sum of the 2-norm residual
                inv_quality_name - str, name of the inversion quality parameter
                                   temporalCoherence for phase
                                   residual          for offset
                weight_sqrt      - 2D np.ndarray in size of (num_pair, num_pixel),
                                   weight square root, None for un-weighted estimation.
    Returns:    inv_quality      - 1D np.ndarray in size of (num_pixel), temporalCoherence / residual
    )r   g     jAz=calculating {} in chunks of {} pixels: {} chunks in total ...r   r   Ny              ?r   )r   r   r      zchunk {} / {}z&un-recognized inversion quality name: )r   r   r   r   intrz   
round_to_1ceilr\   rV   ranger   r   absr   expr   r   r   maxrU   )r   r   r   r   r   r   rL   num_pairr   r   
chunk_size	num_chunkrs   c0c1eZ
chunk_steprA   rA   rB   r     s@    

0,

0(4
$

 r   r   c             C   s  t | }|jdd |j}|j}|jd |j d | | d }tt|d |d  }tt	|| d d }tt|| }|r|d	krt
d
|  t
d||f  t
d|  g }	x>t|D ]2}
|
| }t||| g}d|||f}|	| qW |	|fS )a4  Split into chunks in rows to reduce memory usage
    Parameters: dataset_shape - tuple of 3 int
                max_memory    - float, max memory to use in GB
                print_msg     - bool
    Returns:    box_list      - list of tuple of 4 int
                num_box       - int, number of boxes
    F)rL   r   r   r   g      ?i   @
   r   zmaximum memory size: %.1E GBz-split %d lines into %d patches for processingz"    with each patch up to %d linesr   )r   rc   lengthwidthr   numDater   r   r   rintr\   r   r   append)ifgram_file
max_memoryrL   Zifg_objr   r   ds_sizenum_boxy_stepbox_listrs   y0y1boxrA   rA   rB   split2boxes1  s&     r   r'   c             C   s   t | jdd}t |d }|dkrNtj||jd k rtd td nTtj||jd k rtd td	 td
 td td td td t |S )z<
    Check Rank of Design matrix for weighted inversion
    T)r   r   r)   r   z@WARNING: singular design matrix! Inversion result can be biased!z-continue using its SVD solution on all pixelszERROR: singular design matrix!z;    Input network of interferograms is not fully connected!z6    Can not invert the weighted least square solution.zYou could try:zC    1) Add more interferograms to make the network fully connected:z6       a.k.a., no multiple subsets nor network islandsz8    2) Use '-w no' option for non-weighted SVD solution.)	r   r   get_design_matrix4timeseriesr   r   matrix_rankr   r\   	Exception)r   weight_funcdate12_listr   rA   rA   rB   check_design_matrixT  s     
r   rG   c          	   C   s   | j |dd }|r&td||| | j|||dd|d}|dk	rV|rtd nJd	| jkr|rltd
 t| jd}|d	 dd }W dQ R X nt	dxDt
|D ]8}	||	ddf dk}
||	ddf |
  ||	 8  < qW |S )a&  Read unwrapPhase / azimuthOffset / rangeOffset from ifgramStack file

    Parameters: stack_obj - ifgramStack object
                box       - tuple of 4 int
                ref_phase - 1D array or None
    Returns:    stack_obs - 2D array of unwrapPhase in size of (num_pair, num_pixel)
    )r   r   zreading {} in {} * {} ...F)datasetNamer   r   rL   r   Nzuse input reference valuerefPhasezread reference phase from filer   zJNo reference value input/found on file! unwrapped phase is not referenced!g        )get_sizer\   rV   readr   rd   r   r   filer   r   )rn   r   	ref_phaseobs_ds_namer   rL   r   	stack_obsr   rs   r1   rA   rA   rB   read_stack_obsl  s(    


$r  皙?c       
      C   s  |j |dd }|r||jkr|r4td||| |j|||dd|d}	d|	t|	< |dkrx|rtd| n\|d	kr|	|k}	|rtd
|| n6|dr|	|k}	|rtd|| nt	d|tj
| |	dk< |dk	rtj
||	dk< ~	| |fS )z5Mask input unwrapped phase by setting them to np.nan.)r   r   zreading {} in {} * {} ...F)r   r   r   rL   r   )connectComponentz3mask out pixels with {} == 0 by setting them to NaN)	coherence	offsetSNRz3mask out pixels with {} < {} by setting them to NaN	OffsetStdz3mask out pixels with {} > {} by setting them to NaNz#Un-recognized mask dataset name: {}g        N)r  rd   r\   rV   r  r   r   r   endswithrU   r   )
r  rn   r   mask_ds_namemask_threshold	stack_stdr   rL   r   Zmsk_datarA   rA   rB   mask_stack_obs  s4    
r  c             C   sP   | j |dd }|r$td|| | jd||dd|d}d|t|< |S )	z 
    Read spatial coherence
    )r   r   z reading coherence in {} * {} ...r
  F)r   r   r   rL   r   g        )r  r\   rV   r  r   r   r   )rn   r   r   rL   r   Zcoh_datarA   rA   rB   read_coherence  s    r  順 c             C   s`  t d t| ||d}|jd }d| j kr>t| jd }n$t| jd t| jd  }|d }tt	|
td}tt|| }t dj||d	 xt|D ]}	|	| }
t|	d | |}|	d
krd}nd}tj|dd|
|f ||d|d|dd|
|f< t|dd|
|f |dd|
|f< |	d d d
krt d|	d | qW |S )zTRead coherence and calculate weight_sqrt from it, chunk by chunk to save memory
    z-calculating weight from spatial coherence ...)r   r   r   Z
NCORRLOOKSALOOKSRLOOKSg
ףp=
?zLconvert coherence to weight in chunks of {c} pixels: {n} chunks in total ...)cnr   TFNg?)LepsilonrL   zchunk {} / {})r\   r  r   metadatar`   r=   r   r   r   r   r   r   rV   r   r   decorZcoherence2weightr   )rn   r   r   r   r   weightr   r  r   rs   r   r   rL   rA   rA   rB   calc_weight_sqrt  s4    
*r  c       	      C   s   t jt j| j}t j|d}t|d }|dkrXt j|d}t j|sXd}|rt j|rtt	j
|tdt}|sd}|d7 }t|| jd	d
}| jd	d
}| j||dd }t	||k}|||fS )z6Get the design matrix for time-series STD calculation.zsmallbaselineApp.cfgzmintpy.reference.dateautozreference_date.txtN)r   z;reference date is required for time-series STD calculation,z'but NOT found in mintpy.reference.date!T)r   )refDater   )r]   r^   dirnamer  joinr   ry   r_   r;   r   loadtxtbytesr   rU   r   get_date_listr   array)	rn   Z
mintpy_dirZcfg_filer"   ro   r   	date_listA_stdflag_stdrA   rA   rB   get_design_matrix4std   s$    r)  Fc       9      C   s  t | }|jdd |r:|d |d  }|d |d  }n|j}|j}|| }|jdd}t|}tt	|d tj
d	 }t|d
d}|jdd}|j|ddd \}}d}d}|dr(|dkrt|||ddd}|
rt|dd \}}|dkrd| }ndt||dddd }nd| kr|
sF|dkrtd|d |t| |j|d |dddt|d
}d|t|< d||dk < td d| }|
rt|dd \}}d| }|dkrd}n"|dkrntd| d| dntd| t||||dd}d| krLtj||d k< td!| t||||||dd"\}}t|tj}|rtd#tj| t !|}t"|d$ t"|d%  }}||f|j|jfkrtd&t #|}d'd( |D d } t j|| |d)d $ }!|tj|!tjd*9 }~!td+| |tj%t|dd, 9 }tj&tj'| d-}"d.}#d| krtj&tj'| d/}"d0}#|"rtj(|"rtd1tj|" t j|"|d2d $ }$||$d k9 }~$t"t)|}%t*|d }&td3|%||%| d4  t+||ftj
}'t+||ftj
}(t+|tj
})d| krT|)tj9 })t+|tj,}*|%dk r|'|||}'|(|||}(|)||})|*||}*|'|(|)|*|fS |dkrRtj%t| dd,}+|+|9 }+||+A },~t)|+dkr`td5|t)|+t)|+|% d4  t-|||dd|+f |d||	|#d6\}-}.}/|-|'dd|+f< |.|)|+< |/|*|+< t)|,dkrtd7|t)|,t)|+|% d4  t"t)|,}0t*|,d }1tj.|0d8}2xt/|0D ]|}3|1|3 }4t-|||dd|4f |d||	|#d6\}-}.}/|-$ |'dd|4f< |.|)|4< |/|*|4< |2j0|3d d9d:|3d |0d; qW |21  ntd< tj.|%d8}2xt/|%D ]}3|&|3 }4t-|||dd|4f ||dd|4f ||	|#d6\}-}.}/|-$ |'dd|4f< |.|)|4< |/|*|4< |2j0|3d d9d:|3d |%d; qpW |21  ~|
rtd= tj.|%d8}2xrt/|%D ]f}3|&|3 }4t2||dd|4f |dd|4f |	d>}5|5$ |(||4f< |2j0|3d d9d:|3d |%d; q*W |21  ~~|'|||}'|(|||}(|)||})|*||}*|drd
t3|j4d?  d@tj5  }6|'|69 }'|(t6|69 }(tdA n|dBk|j4dC dDk@ rrt78|j4}7|7t3|j4dE  }7|'|79 }'|(|79 }(tdF|7 nZ|dGk|j4dC dDk@ rt3|j4dH }8|8t3|j4dI  }8|'d
|8 9 }'|(|89 }(tdJ|8 |'|(|)|*|fS )Ka  Invert one patch of an ifgram stack into timeseries.

    Parameters: box               - tuple of 4 int, indicating (x0, y0, x1, y1) of the area of interest
                                    or None for the whole image
                ifgram_file       - str, interferograms stack HDF5 file, e.g. ./inputs/ifgramStack.h5
                ref_phase         - 1D array in size of (num_pair), or None
                obs_ds_name       - str, dataset to feed the inversion.
                weight_func       - str, weight function, choose in ['no', 'fim', 'var', 'coh']
                water_mask_file   - str, water mask filename if available, to skip inversion on water
                min_norm_velocity - bool, minimize the residual phase or phase velocity
                mask_ds_name      - str, dataset name in ifgram_file used to mask unwrapPhase pixelwisely
                mask_threshold    - float, min coherence of pixels if mask_dataset_name='coherence'
                min_redundancy    - float, the min number of ifgrams for every acquisition.
    Returns:    ts/ts_std         - 3D array in size of (num_date, num_row, num_col)
                inv_quality       - 2D array in size of (num_row, num_col)
                num_inv_obs       - 2D array in size of (num_row, num_col)
                box               - tuple of 4 int
    Example:    ifgram_inversion_patch('ifgramStack.h5', box=(0,200,1316,400))
    F)rL   r   r   r   r   T)r   g     v@r   )r   N)rG   rR   )r)   Zsbasi )r   r   r   r'   g      ?rM   zreading {} in {} * {} ...Std)r   r   r   rL   g      Y@g{Gzt?z,convert std. dev. to the inverse of variancezun-supported weight_func = z for !z(un-recognized observation dataset name: )r  r   phaseg        z/convert zero value in {} to NaN (no-data value))r  r  r  r   z6skip pixels (on the water) with zero value in file: {}LENGTHWIDTHz?Input water mask file has different size from ifgramStack file.c             S   s   g | ]}|d kr|qS ))	waterMaskr1   rA   )rr   rs   rA   rA   rB   rt     s    z*ifgram_inversion_patch.<locals>.<listcomp>)r   r   )r   z/skip pixels with {} = NaN in all interferograms)r   z../avgSpatialCoh.h5r   z../avgSpatialSNR.h5r   z'skip pixels with zero value in file: {})r   z2number of pixels to invert: {} out of {} ({:.1f}%)d   z\estimating time-series for pixels with valid {} in all  ifgrams ({:.0f} pixels; {:.1f}%) ...)r   r   r   r   r   r   z\estimating time-series for pixels with valid {} in some ifgrams ({:.0f} pixels; {:.1f}%) ...)maxValue   z{}/{} pixels)everysuffixz1estimating time-series via WLS pixel-by-pixel ...zepropagating std. dev. from network of interferograms to time-series (Yunjun et al., 2021, FRINGE) ...)r   r   r   
WAVELENGTHg      @z.converting LOS phase unit from radian to meterrP   	PROCESSORcosicorrr  z=converting azimuth offset unit from pixel ({:.2f} m) to meterrQ   RANGE_PIXEL_SIZEr  z;converting range offset unit from pixel ({:.2f} m) to meter)9r   rc   r   r   r$  r   r   r%  r	   date_list2tbaser   diffr   r   r   re   r  r)  ra   r\   rV   r  r   rU   r  r   r  onesbool_r]   r^   basenamer   rT   r   get_dataset_listr   r   r!  r   r_   r   wherer   int16r   progressBarr   updatecloser   r=   r  pir   rz   azimuth_ground_resolution)9r   r   r  r  r   water_mask_filer   r  r  r   calc_stdrn   num_rownum_colr   r&  r   tbaser   r   r   r   r   r  r'  r(  r  r1   Zatr_mskZlen_mskZwid_mskdsNamesdsNamer/  Zstack_quality_filer   qualitynum_pixel2invidx_pixel2invr   r   r   r   Zmask_all_netZmask_part_netZtsiZ	inv_qualiZnum_obsiZnum_pixel2inv_partZidx_pixel2inv_partprog_barrs   idxZts_stdiphase2rangeaz_pixel_sizeZrg_pixel_sizerA   rA   rB   ifgram_inversion_patch   s   










&
&&
rT  c       *      C   s  | s
t  } t }td}t| j}|jdd |jdd}|jdd}|j	|j
 }}|j| j| jdd| _||d }|jd |jd d  }	}
|	| _| jrt|d	 }d
| }nd}d}| jrd}nd}|d|7 }|d| j7 }|d| j7 }|d| j|7 }| jr| jdkr4d| j}nN| jdkrRd| j| j}n0| jdrrd| j| j}ntd| j|d|7 }n|d7 }tj||jd k r|d7 }|d7 }|d7 }|d7 }t| td |	 td!|
 td"| td#| t |j!}x&t"D ]}t#t$| | |t%| < q"W d$|d%< d&|d'< |d |d(< tj&|tj'd)}|j(dd}|j)|
f|gtj*|
f|gtj*|
||fd*gd+}t+j,| j-||d, | jrt.j/0| j-d }| j1d-r|d.7 }| d/}||d(< t+,||| d0t.j/2| j34 kr2d0}d1|d'< nd2}d|d'< ||d%< |5d( |d% tj*||fgi}t+j,| j3||d, d3|d%< d|d'< d3tj*||fgi}t+j,| j6||d, t7| j| j8d4\}}| j| j| j| j| j| j9| j| j| j| jd5
}xt:|D ]\}}|d	 |d  }|d6 |d  }|dkr^td7|d | td8| td9| ||d:< | jst;f |d*d; \}}} }!ntd< t<|
||ftj*}t<|
||ftj*}t<||ftj*} t<||ftj*}!tj=| j| j>| j?d=}"|"  |"j@t;|||| |!gd>\}}} }!|"A  td? d|
|d |d6 |d |d	 g}#t+jB| j-|d$|#d@ | jrzt+jB||d$|#d@ |d |d6 |d |d	 g}#t+jB| j3| ||#d@ t+jB| j6|!d3|#d@ |dkrtCt | dA\}$}%tdB|$|% qW | jstD|j!dC }&tD|j!dD }'tdE tdF|&|' |d0kr>dnd}(tdG||( tEF| j3dH})|(|)| |&|'f< W d*Q R X tdI|	 tEF| j6dH})|	|)d3 |&|'f< W d*Q R X tG| tCt | dA\}$}%tdB|$|% d*S )JzPhase triangulatino of small baseline interferograms

    Parameters: inps - namespace
    Example:    inps = cmd_line_parse()
                ifgram_inversion(inps)
    rF   F)rL   T)r   )unwDatasetNameskip_referencer   r   r   r   z with REF_DATE = rK   zP-------------------------------------------------------------------------------
zdeformation velocityzdeformation phasez/least-squares solution with L2 min-norm on: {}
zminimum redundancy: {}
zweight function: {}
zcalculate STD: {} {}
)r	  z{} == 0)r
  r  z{} < {}r  z{} > {}z#Un-recognized mask dataset name: {}zmask out pixels with: {}
z	mask: no
z0***WARNING: the network is NOT fully connected.
z!	Inversion result can be biased!
zF	Continue to use SVD to resolve the offset between different subsets.
zO-------------------------------------------------------------------------------znumber of interferograms: {}znumber of acquisitions  : {}znumber of lines   : {}znumber of columns : {}r   rE   mUNITREF_DATE)r   N)datebperpr   )r  rG   ZDecorzStd.h5r   pixelr   r1   )r   )
r   r  r  r   r   rF  r  r  r   rG  r   z5
------- processing patch {} out of {} --------------zbox width:  {}zbox length: {}r   r   z6

------- start parallel processing using Dask -------)config_name)func	func_dataresultsz.------- finished parallel processing -------

)datar   block<   z(time used: {:02.0f} mins {:02.1f} secs.
rO   rN   z2--------------------------------------------------z.update values on the reference pixel: ({}, {})z$set {} on the reference pixel to {}.zr+z3set  # of observations on the reference pixel as {})Hrp   timer   set_num_threadsr   r   rc   r   r$  r   r   get_reference_phaser   r#   r   r   r   r   r0   r)  r   rV   r   r   r   r   r  rU   r   r   r   r\   rX   r  r   r;   rx   rq   r%  string_get_perp_baseline_timeseriesr   r   r   layout_hdf5rf   r]   r^   splitextre   r=  rg   ra   poprh   r   rw   r   r   rT  r   rY   r[   rv   r   rC  write_hdf5_blockdivmodr   r   r   roll_back_num_threads)*rj   
start_timenum_threads_dictrn   r   r&  r   r   r   r   r   Zref_date4stdZref_msgro   r4  metarm   datespbaseds_name_dictfbaseZ	tsStdFiler   r   r   data_kwargsrs   r   box_widbox_lenr   r   r   r   cluster_objrb  rW  sref_yref_xref_valr   rA   rA   rB   ifgram_inversion_  s.   









 

r~  c             C   sB   t | }|jr t|dkr |jS |jdkr4t| ntd|jS )Nr   r.   z)L1 norm minimization is not fully tested.)rp   r3   r   r   r-   r~  NotImplementedError)ri   rj   rA   rA   rB   maina  s    

r  __main__r   )N)NTr   r   r   T)r   r   )r   NT)r   T)r'   )rG   TT)Nr  NTT)TT)r'   Tr  )
NNrG   r'   NTNr  r   F)N)N)1r]   sysrd  r4   r   numpyr   scipyr   mintpy.objectsr   r   Zmintpy.simulationr   r  mintpy.defaults.templater   mintpy.utilsr   r   r	   r
   rz   r   rq   r   r9   r8   r7   rC   rp   rW   r   r   r   r   r   r   r   r  r  r  r  r)  rT  r~  r  __name__argvrA   rA   rA   rB   <module>   sf   ?
J(5  
}
%
M
#
 
) 
*

/   
  ?
  

