U
    bbUR                     @   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 d dl	m
Z
 d dlmZmZmZ e
dZdZdZ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 Zd d! Zd,d"d#Ze d$k reej!d%d  dS )-    N)
timeseries)get_template_content)readfile	writefileutilsreference_pointa  note: Reference value cannot be nan, thus, all selected reference point must be:
  a. non zero in mask, if mask is given
  b. non nan  in data (stack)
  
  Priority:
      input reference_lat/lon
      input reference_y/x
      input selection_method
      existing REF_Y/X attributes (can be ignored by --force option)
      default selection methods:
          maxCoherence
          random

  The recommended reference pixel should meets the following criteria:
  1) not in deforming areas
  2) not in areas affected by strong atmospheric turbulence, such as ionospheric streaks
  3) close but outside of deforming area of interest with similar elevation, to minimize
     the spatial correlation effect of atmosspheric delay, especially for shot-wavelength
     deformation (Chaussard et al., 2013; Morales-Rivera et al., 2016)
  4) in high coherent area to minimize the decorrelation effect
a  example:
  # for ifgramStack file, update metadata only
  # add --write-data to update data matrix value
  reference_point.py  inputs/ifgramStack.h5  -t smallbaselineApp.cfg  -c avgSpatialCoh.h5
  reference_point.py  inputs/ifgramStack.h5 --method manual
  reference_point.py  inputs/ifgramStack.h5 --method random

  # for all the other files, update both metadata and data matrix value
  reference_point.py  091120_100407.unw -y 257    -x 151      -m Mask.h5
  reference_point.py  geo_velocity.h5   -l 34.45  -L -116.23  -m Mask.h5
c                  C   s^  t jdt jtd t d t d} | jdtdd | jddd	d
d | jddddd | jddtd dd | jddddd | jdddd | jdddd | d}|jdd d!t	d"d# |jd$d%d&t	d'd# |jd(d)d*t
d+d# |jd,d-d.t
d/d# |jd0d1d2d3d |jd4d5d6d7d | jd8d9d:d;d<d= | jd>d?t
d@dAdB | jdCtdDdEdFgdGdH | S )INz%Reference to the same pixel in space.
)descriptionformatter_classepilogfilezfile to be referenced.)typehelpz-tz
--templatetemplate_fileztemplate with reference info)destr   z-mz--maskmaskFilez	mask filez-oz	--outfilezoutput file name (default: %(default)s). This option is diabled for ifgramStack file.
None (default) for update data value directly without writing to a new file.
)r   defaultr   z--write-data
write_data
store_truezU(option for ifgramStack file only) update data value, in addition to update metadata.)r   actionr   z--resetz>remove reference pixel information from attributes in the file)r   r   z--forcez,Enforce the re-selection of reference point.zinput coordinatesz-yz--rowref_yz&row/azimuth  number of reference pixel)r   r   r   z-xz--colref_xz&column/range number of reference pixelz-lz--latref_latzlatitude  of reference pixelz-Lz--lonref_lonzlongitude of reference pixelz-rz--referencereference_filez$use reference/seed info of this filez--lookupz--lookup-filelookup_filez{Lookup table file from SAR to DEM, i.e. geomap_4rlks.trans
Needed for radar coord input file with --lat/lon seeding option.z-cz--coherencecoherenceFilezaverageSpatialCoherence.h5zRuse input coherence file to find the pixel with max coherence for reference pixel.)r   r   r   z--min-coherenceminCoherence333333?z>minimum coherence of reference pixel for max-coherence method.)r   r   r   r   z--methodmaxCoherencemanualrandomaZ  methods to select reference pixel if not given in specific y/x or lat/lon:
maxCoherence : select pixel with highest coherence value as reference point
               enabled when there is --coherence option input
manual       : display stack of input file and manually select reference point
random       : random select pixel as reference point
)r   choicesr   )argparseArgumentParserRawTextHelpFormatterNOTETEMPLATEEXAMPLEadd_argumentstradd_argument_groupintfloat)parsercoord r0   L/home/centos/operations/rsmas_insar/sources/MintPy/mintpy/reference_point.pycreate_parser:   sh    



 
 

r2   c                 C   sD   t  }|j| d}t|j}|d dkr2d|_n|jr@td|S )zCommand line parser.)args	FILE_TYPEifgramStackTz3--outfile is disabled for "ifgramStack" input file!)r2   
parse_argsr   read_attributer   r   outfile
SystemExit)iargsr.   inpsatrr0   r0   r1   cmd_line_parsem   s    r=   c                    s.  |st dg}t|}t| td  fddt|D }|D ]:} |  }|rJ|dkrp|||< qJ|dkrJt|||< qJ d }| krֈ| }|r|	dd	d	d}d
d |
dD \|_|_ d }| kr*| }|r*|	dd	d	d}dd |
dD \|_|_|S )zFRead seed/reference info from template file and update input namespace zmintpy.reference.c                    s    g | ]} |   kr|qS r0   )keys.0iprefixtemplater0   r1   
<listcomp>   s    z+read_template_file2inps.<locals>.<listcomp>)r   r   r   Zyx[]c                 S   s   g | ]}t |qS r0   )r,   r@   r0   r0   r1   rF      s     ,Zlaloc                 S   s   g | ]}t |qS r0   )r-   r@   r0   r0   r1   rF      s     )r=   varsr   read_templateutcheck_template_auto_valuelistr-   r?   replacesplitr   r   r   r   )r   r;   	inps_dictkey_listkeyvaluer0   rC   r1   read_template_file2inps   s6    



rU   c                 C   s:   t ||  d }t|t |kr2|t|k}ng }|S )z find nearest neighbour    )npsqrtminabs)xtbasexstepdistindxr0   r0   r1   nearest   s
    r`   c              	   C   s  | st dg} t| j}| jsn| jdk	rn| jt|ddkrn| jdk	rn| jt|ddkrnt	d | jS |d dkrd	d
 t
| jD d }nd}tj| j|dddd }tt| |dk}t|dkrtd| jdk	r| jdk	r|| j| jf dkrtdn~| jdkr@t| j|| jd\| _| _n6| jdkr^t|\| _| _n| jdkrvt|| |} | jdks| jdkrtdt|| j| jd}| jst	d| j  t	| t| j|| _n| js| j| _|d }tj| jd }|dkr| j| jkrTt	d |dkrt | jdd}|d }	t!|	j"d D ]2}
|	|
ddddf  |	|
| j| jf 8  < qTt	d |j#$| W 5 Q R X nt | jd}|| }	t%|	j"dkrt!|	j"d D ]2}
|	|
ddddf  |	|
| j| jf 8  < qn |	dd  |	| j| jf 8  < t	d |j#$| W 5 Q R X nt	d &| j t'| j\}}t%|j"dkrt!|j"d D ]2}
||
ddddf  ||
| j| jf 8  < qn||| j| jf 8 }|$| t(j)|| j|| jd! nd"d#g}t
| j}i }|D ]V}tj'| j|d$d }||krR||| j| jf 8 }nt	d%| d&|  |||< q|$| t(j)|| j|d' t*| j| j+g | jS )(ztSeed input file with option from input namespace
    Return output file name if succeed; otherwise, return None
    r>   NREF_YiREF_XzFSAME reference pixel is already selected/saved in file, skip updating.r4   r5   c                 S   s   g | ]}|d kr|qS ))unwrapPhaserangeOffsetazimuthOffsetr0   r@   r0   r0   r1   rF      s    z"reference_file.<locals>.<listcomp>r   TF)datasetName
updateModeoutFile        z6no pixel found with valid phase value in all datasets.z?reference y/x have nan value in some dataset. Please re-select.r   )coh_filemaskmin_cohr!   r    zERROR: no reference y/x found.)yr[   z&Add/update ref_x/y attribute to file:    z.h5z4updating data value without re-writing to a new filezr+rc   zupdate metadata   z)writing the referenced data into file: {})metadataref_filephasedisplacementrf   zskip spatial referencing for z, as it's not in )out_filerp   ),r=   r   r7   r   forcer   r,   getr   printget_dataset_listrL   temporal_averagerW   multiplyisnannansum
ValueErrormethodselect_max_coherence_yxr   r   random_select_reference_yxmanual_select_reference_yxreference_point_attributer   add_attributer8   ospathsplitexth5pyFilerangeshapeattrsupdatelenformatreadr   writetouchr   )r;   r<   ds_namestackrk   atrNewkfextfdsrB   dataZ	dis_namesds_namesZds_dictr0   r0   r1   r      s    



02 2


r   c                 C   sd   t  }t||d< t||d< t| }d|  kr`t|j|dd|d< t|j|dd|d< |S )	Nra   rb   X_FIRSTrm   )
coord_typeREF_LATr[   REF_LON)dictr*   rL   
coordinater?   yx2lalo)r<   rm   r[   r   r/   r0   r0   r1   r   0  s    
r   c                    s   ddl m} td td td td |dk	rBtj |dk< | }|d}|   fd	d
}|j	d|}|
  tdjjf S )zManually select reference point in row/column number.
    Parameters: data : 2D np.ndarray, stack of input file
                inps : namespace, with key 'REF_X' and 'REF_Y', which will be updated
                mask : 2D np.ndarray
    r   )pyplotz"
Manual select reference point ...z9Click on a pixel that you want to choose as the refernce z&    pixel in the time-series analysis;z-Then close the displayed window to continue.
No   c                    s~   | j dkrztd t| jd }t| jd }t | | sbtdt||g  |_|_	ntd td td d S )Nrn   clickg      ?zvalid input reference y/x: z	
WARNING:z(The selectd pixel has NaN value in data.z!Try a difference location please.)
buttonrx   r,   xdataydatarW   r|   r*   r   r   )eventr[   rm   r   r;   r0   r1   onclickS  s    
z+manual_select_reference_yx.<locals>.onclickbutton_press_eventy/x: {})
matplotlibr   rx   rW   nanfigureadd_subplotimshowcanvasmpl_connectshowr   r   r   )r   r;   rk   pltfigaxr   cidr0   r   r1   r   <  s    

r   r   c           	      C   s   t d| t d|   t| \}}|dk	r<d||dk< ||k}t|dkr|d|}|d7 }|d7 }|d	7 }t|t|d
d\}}t d||f ||fS )z/Select pixel with coherence > min_coh in randomz'random select pixel with coherence > {}z	based on coherence file: Nri   r   z_No pixel with average spatial coherence > {} are found for automatic reference point selection!z
Try the following:zQ
  1) manually specify the reference point using mintpy.reference.yx/lalo option.z<
  2) change mintpy.reference.minCoherence to a lower value.F)	print_msgr   )rx   r   r   r   rW   allRuntimeErrorr   )	rj   rk   rl   cohZcoh_atrZcoh_maskmsgrm   r[   r0   r0   r1   r   h  s"    r   Tc                 C   s   t | \}}ttt|}ttt|}| ||f dkrhttt|}ttt|}q2|r~td||f ||fS )Nr   zrandom select pixel
y/x: {})rW   r   r!   choicerN   r   rx   r   )Zdata_matr   nrowncolrm   r[   r0   r0   r1   r   ~  s    r   c                 C   s   |st dg}t|j}|jdks.|jdkrVd| krVt|d |_t|d |_|jdksj|j	dkrd| krt
|d |_t
|d |_	|S )zBRead reference info from reference file and update input namespacer>   Nrb   ra   r   r   )r=   r   r7   r   r   r   r?   r,   r   r   r-   )r   r;   ZatrRefr0   r0   r1   read_reference_file2inps  s    
  r   c                 C   s  t | j}t|d }t|d }d| _| jrLt| j | j| _d| _| S td | j	rttd| j	  t
| j	| } | jrtd| j  t| j| } | jrt| jdkrd	| krd
| j d}|d7 }t|tj|| jd}| jr6| jr6|t| jt| jdd \| _| _td| j| jf | jd k	r$| jd k	r$td| j| jf d| j  kr~|k rn nd| j  kr|k sn d\| _| _td| jrtj| jrtd| j  t j| jddd }|| j| jf dkrd\| _| _d| j}t|ntd | j s| j!sd| krdt"|d   krj|krn n\dt"|d   kr|krn n8td td|d   td|d   | j| _d| _n&| j#rtj| j#rd| _ nd| _ td t$| j   td | S )!NLENGTHWIDTHTFz2--------------------------------------------------z&reading reference info from template: z'reading reference info from reference: Z   UTM_ZONEzinput reference latitude (z) > 90 deg in magnitude!z4 This does not make sense, double check your inputs!)r   r   rV   z$input reference point in lat/lon: {}z input reference point in y/x: {})NNz.input reference point is OUT of data coverage!zmask: rk   rt   z:input reference point is in masked OUT area defined by {}!zno input reference y/x.rb   ra   z,REF_Y/X exists in input file, skip updating.zREF_Y: zREF_X: r   r!   z"reference point selection method: )%r   r7   r   r,   go_referenceresetremove_reference_pixelr8   rx   r   rU   r   r   r   rW   rZ   r?   r~   rL   r   r   r   	geo2radararrayr   r   r   r   r   r   isfiler   r   rv   r-   r   r*   )r;   r<   lengthwidthr   r/   rk   r0   r0   r1   read_reference_input  s    
"
 :

 

 

r   c                 C   s2   t d|   i }dD ]}d||< qt| |} | S )z+Remove reference pixel info from input filez-remove REF_Y/X and/or REF_LAT/LON from file: )rb   ra   r   r   None)rx   rL   r   )r   ZatrDroprB   r0   r0   r1   r     s    
r   c                 C   s<   t | }t|jd |_t|}|jr0t| td d S )Nr   zDone.)r=   rL   get_file_listr   r   r   r   rx   )r:   r;   r0   r0   r1   main  s    r   __main__rn   )N)N)N)Nr   )T)N)N)"r   sysr#   r   numpyrW   r!   mintpy.objectsr   mintpy.defaults.templater   mintpy.utilsr   r   r   rL   r'   r&   r(   r2   r=   rU   r`   r   r   r   r   r   r   r   r   r   __name__argvr0   r0   r0   r1   <module>	   s6   3

%
 
,


N

