U
     cY                     @   s   d dl Z d dlZd dlZd dlZd dlmZmZmZm	Z
mZ d dlmZ dZdZdddZddd	Zd
d Zdd Zdd Zdd Zdd ZejfddZd ddZdd Zd!ddZedkreejdd  dS )"    N)ptimereadfile	writefileutils	attribute)create_argument_parsera  template
## if both yx and lalo are specified, use lalo option unless a) no lookup file AND b) dataset is in radar coord
mintpy.subset.yx       = auto    #[1800:2000,700:800 / no], auto for no
mintpy.subset.lalo     = auto    #[31.5:32.5,130.5:131.0 / no], auto for no
a  example:
  subset.py inputs/ifgramStack.h5 -y 400  1500 -x 200   600
  subset.py geo_velocity.h5       -l 30.5 30.8 -L 130.3 130.9
  subset.py 030405_090801.unw     -t SinabungT495F50AlosA.template

  # subset to the same coverage as the reference file
  subset.py geo_incidence.h5 -r subset_geo_velocity.h5

  # multiple files input
  subset.py *velocity*.h5 timeseries*.h5  -y 400 1500  -x 200 600

  # crop to larger area with custom fill value 
  subset.py geo_velocity.h5 -l 32.2 33.5  --outfill-nan
  subset.py Mask.h5 -x 500 3500 --outfill 0

  # "tight" subset for geocoded lookup table larger than data file
  subset.py geomap_4rlks.trans --tight
c              
   C   s  d}t d t }tdd }t||||| d}|jdddd	 |jd
dddtddd |jddddtddd |jdddddtddd |jddddd tdd!d |jd"d#d$d%d& |jd'd(d)d* |jd+d,d-d. |jd/d0td1d2 |jd3d4d5d6d& |d7d8}|jd9d:d;d& |S )<Nz#Generate a subset from file/dataset
.)synopsisdescriptionepilog
subparsersfile+zFile(s) to subset/crop)nargshelpz-xz--sub-xz
--subset-xsubset_x   z.subset range in x/cross-track/column direction)desttyper   r   z-yz--sub-yz
--subset-ysubset_yz+subset range in y/along-track/row directionz-lz--latz	--sub-latz--subset-lat
subset_latzsubset range in latitudez-Lz--lonz	--sub-lonz--subset-lon
subset_lonzsubset range in column

z-tz
--templatetemplate_filez}template file with subset setting.  i.e. 
mintpy.subset.yx    = 300:800,1000:3500
mintpy.subset.lalo  = 30.2:30.5,130.1:131.3)r   r   z-rz--referencez9reference file, subset to the same lalo as reference file)r   z--tight
store_truezsubset geomap_*.trans file based on non-zero values.
For geocoded file(s) onlyA convenient way to get rid of extra wide space due to "too large" DEM.

)actionr   z	--outfill
fill_valuezyfill subset area out of data coverage with input value. i.e. 
np.nan, 0, 1000, ... 
By default, it's None for no-outfill.)r   r   r   z-oz--outputoutfilezloutput file name
add prefix "sub_" if input/output files are in the same directory;
same filename otherwise.DatasetszpCreate a subset of entire dataset in radar using y/x or lat/lon option
Including *.trans and *.dem in geo coord.z--lookuplookup_filezcalculate bounding box in geo/radar coord from input radar/geo subset range
using transformation file, i.e. geomap_4rlks.trans
All input radar coord file should be same size/coverage; same for all geo coord files.)	TEMPLATEEXAMPLE__name__splitr   add_argumentintfloatadd_argument_group)r   r   r   nameparserZ
dset_group r+   D/home/exouser/operations/rsmas_insar/sources/MintPy/mintpy/subset.pycreate_parser2   sb            


r-   c                 C   s8   t  }|j| d}t|j|_t|jdkr4d |_|S )N)args   )r-   
parse_argsutget_file_listr   lenr   )iargsr*   inpsr+   r+   r,   cmd_line_parsec   s    r6   c                    s   t  d }t  d }t fdddD rt d }t d }t d }t d	 }|||  }|||  }||||f}	nd
}	t fdddD rt  d t  d t  d t  d f}
nd
}
|
|	fS )zGet Coverage Box of data in geo and pixel coordinates
    Inputs: atr - dict, meta data dictionary
    Outputs:
        pix_box : 4-tuple of int, defining in (UL_X, UL_Y, LR_X, LR_Y)
        geo_box : 4-tuple of float in lat/lon
    LENGTHWIDTHc                 3   s   | ]}|   kV  qd S Nkeys.0xatrr+   r,   	<genexpr>|   s     z#get_coverage_box.<locals>.<genexpr>)Y_STEPX_STEPY_FIRSTX_FIRSTrB   rC   rD   rE   Nc                 3   s    | ]}d |    kV  qdS )ZSUBSET_Nr:   r<   r?   r+   r,   rA      s     )YMINXMINYMAXXMAXSUBSET_XMINSUBSET_YMINSUBSET_XMAXSUBSET_YMAX)r&   allr'   )r@   lengthwidthlat_steplon_stepZul_latZul_lonZlr_latZlr_longeo_boxpix_boxr+   r?   r,   get_coverage_boxp   s&    



rU   c                 C   s  t | }zhdd |d dD }tdd |d dD \}}tdd |d	 dD \}}||||f}W n   d
}Y nX zhdd |d dD }tdd |d dD \}}	tdd |d	 dD \}
}|
|||	f}W n   d
}Y nX ||fS )ziRead mintpy.subset.lalo/yx option from template file into box type
    Return None if not specified.
    c                 S   s$   g | ]}|  d dddqS [ ]stripreplacer=   ir+   r+   r,   
<listcomp>   s     z,read_subset_template2box.<locals>.<listcomp>zmintpy.subset.lalo,c                 S   s   g | ]}t | qS r+   r'   r[   r]   r+   r+   r,   r_      s     r   :c                 S   s   g | ]}t | qS r+   ra   r]   r+   r+   r,   r_      s     r/   Nc                 S   s$   g | ]}|  d dddqS rV   rZ   r]   r+   r+   r,   r_      s     zmintpy.subset.yxc                 S   s   g | ]}t | qS r+   r&   r[   r]   r+   r+   r,   r_      s     c                 S   s   g | ]}t | qS r+   rc   r]   r+   r+   r,   r_      s     )r   read_templater$   sorted)r   tmploptslat0lat1lon0lon1rS   y0y1x0x1rT   r+   r+   r,   read_subset_template2box   s     
  
  
rp   c                 C   sp   |r*|d |d g| _ |d |d g| _nd| _ d| _|r`|d |d g| _|d |d g| _nd| _d| _| S )z9Update inps.subset_y/x/lat/lon from pixel_box and geo_boxr   r   r/      N)r   r   r   r   )r5   rT   rS   r+   r+   r,   subset_box2inps   s    rr   c           
      C   s  t | d |d }t | d |d }t| d |d }t| d |d }||ksX||krd}|d| 7 }|d|7 }t|||||f}|d | d  |d | d  |d | d  |d | d  f}|d |d  |d |d  |d |d  |d |d  f}	||	fS )a[  Get index box overlap area of two input boxes

    Inputs:
        box1/2 : 4-tuple of int, indicating coverage of box1/2
                 defining in (x0, y0, x1, y1)
    Outputs:
        overlap_idx_box1/2 : 4-tuple of int, indicating index of overlap area in box1/2
                             defining in (idx_x0, idx_y0, idx_x1, idx_y1)
    r   r/   r   rq   z(No overlap between two input box range!
z
box 1: {}
z
box 2: {}
)maxminformat
ValueError)
Zbox1Zbox2rn   rl   ro   rm   msgZoverlap_boxZoverlap_idx_box1Zoverlap_idx_box2r+   r+   r,   get_box_overlap_index   s*    rx   c           	      C   s   t t|d }t t|d }t|}| ddrJ|j| d dd}n| d r\| d }nd|g}| d	dr|j| d	 d
d}n| d r| d }nd|g}t|}t|}|d |d |d |d f}||}||fS )aO  Convert subset inputs dict into box in radar and/or geo coord.
    Inputs:
        subset_dict : dict, including the following 4 objects:
                      subset_x   : list of 2 int,   subset in x direction,   default=None
                      subset_y   : list of 2 int,   subset in y direction,   default=None
                      subset_lat : list of 2 float, subset in lat direction, default=None
                      subset_lon : list of 2 float, subset in lon direction, default=None
        meta_dict   : dict, including the following items:
                      'WIDTH'      : int
                      'LENGTH': int
                      'X_FIRST'    : float, optional
                      'Y_FIRST'    : float, optional
                      'X_STEP'     : float, optional
                      'Y_STEP'     : float, optional
    Outputs:
        # box defined by 4-tuple of number, defining (left, upper, right, lower) coordinate,
        #                                            (UL_X, UL_Y,  LR_X,  LR_Y )
        pixel_box   : 4-tuple of int, in pixel unit - 1
        geo_box     : 4-tuple of float, in  lat/lon unit - degree
                      None if file is in radar coordinate.
    example:
        subset_dict = {'subset_x': None, 'subset_y': None, 'subset_lat': [30.5, 31.0], 'subset_lon': [130.0, 131.0]}
        subset_dict = {'subset_x': [100, 1100], 'subset_y': [2050, 2550], 'subset_lat': None, 'subset_lon': None}
        pixel_box          = subset_input_dict2box(subset_dict, meta_dict)[0]
        pixel_box, geo_box = subset_input_dict2box(subset_dict, meta_dict)
    r8   r7   r   Nlatitude)
coord_typer   r   r   	longituder   r/   )r&   r'   r1   
coordinategetlalo2yxre   box_pixel2geo)	subset_dict	meta_dictrP   rO   coordsub_ysub_x	pixel_boxrS   r+   r+   r,   subset_input_dict2box   s$    



r   c           
   	   C   s  t d| d| dtj|  d tj| ||ddd }|j}t|}|dkrt	|d	 |d
  |d |d  f|j
| }	||	|d
 |d	 |d |d f< nh|d	krt	|d |d	 |d
  |d |d  f|j
| }	||	d d |d
 |d	 |d |d f< |	S )Nzreading z in z from  ...F)datasetNamebox	print_msgr   r   rq   r/   )printospathbasenamer   readshaper3   nponesdtype)
fnamedsNamerT   pix_box4datapix_box4subsetr   datads_shapeds_ndimdata_outr+   r+   r,   subset_dataset%  sF    $ 

  r   c                 C   s  t | }t|d }t|d }|d }td| d |  d  | }t||\}}	t|}
d}d| kr|d rd	}nd}|s|
	|}t
j|d< |
|}	d
d
||f}td| td| td|
| td|	 ||krtd | S t||\}}|st tjtj| krd| krv|d rvdtj| d
 tj| d }ndtj|  }ntj| }td|  t||}t | }tj|d }|dkr tj||| d |D ]6}t| d}|| }|j}|j}tdj||tj| d |dkr||d |d |d
 |d f }t
|d |d  |d |d
  f|j |d  }|||d |d |d
 |d f< t
j!||j d}d
t|d d
t|d g}tj"||||d	d |dkrt#j$|d
 d}t%|d
 D ]}|||d |d |d
 |d f }t
d|d |d  |d |d
  f|j |d  }||dd|d |d |d
 |d f< ||d d
t|d d
t|d g}tj"||||dd |j&|d d |d |d
 d! q|'  td"| W 5 Q R X qnt( }|D ]"}t)| |||||d d#||< q*t*| |d$< tj+|||| d% tj,| d& stj,| d' rt-|| |S )(a?  Subset file with
    Parameters: fname       : str, path/name of file
                subset_dict : dict, subsut parameter, including the following items:
                    subset_x   : list of 2 int,   subset in x direction,   default=None
                    subset_y   : list of 2 int,   subset in y direction,   default=None
                    subset_lat : list of 2 float, subset in lat direction, default=None
                    subset_lon : list of 2 float, subset in lon direction, default=None
                    fill_value : float, optional. filled value for area outside of data coverage. default=None
                                 None/not-existed to subset within data coverage only.
                    tight   : bool, tight subset or not, for lookup table file, i.e. geomap*.trans
                out_file    : str, path/name of output file
    Outputs:    out_file    : str, path/name of output file
                    out_file = 'sub_'+fname, if fname is in current directory;
                    out_file = fname, if fname is not in the current directory.
    r8   r7   	FILE_TYPEzsubset z file: r   Fr   Tr   z!data   range in (x0,y0,x1,y1): {}z!subset range in (x0,y0,x1,y1): {}z data   range in (W, N, E, S): {}z subset range in (W, N, E, S): {}z7Subset range == data coverage, no need to subset. Skip.tightz
{}_tight{}r/   Zsub_zwriting >>> )z.h5z.he5)metadataref_filerz cropping {d} in {b} from {f} ...)dbfr   rq   )r   )r   r   blockr   )maxValueNz{}/{})suffixzfinished writing to file: {})r   BANDS)out_filer   r   z.xmlz.aux.xml).r   read_attributer&   r   copyr   r1   r|   r;   check_box_within_data_coverager   nanr   ru   rx   r   getcwdr   dirnameabspathsplitextr   attrupdate_attribute4subsetget_dataset_listr   layout_hdf5h5pyFiler   ndimr   r   arraywrite_hdf5_blockr   progressBarrangeupdateclosedictr   r3   writeisfilewrite_isce_xml)r   Zsubset_dict_inputr   r@   rP   rO   kr   rT   rS   r   Zoutfilldata_boxr   r   dsNamesextr   fidsr   r   r   r   r   prog_barr^   dsDictr+   r+   r,   subset_fileB  s    










  
    $&$r   c                 C   s  t dd | j| j| j| jfD r| jrTt| j}t|\}}t	d| j  nT| j
rzt| j
\}}t	d| j
  n.| jrt| j| _| jstdt| j}t|}d| krJtj| jddd }tj|d	d
\}}t||t|  k\}	}
t|
d t|	d t|
d t|	d f}||}~nTtj| jddd }tj| jddd }t|t|t|t|f}d }~~ntdt| ||} | S )Nc                 s   s   | ]}| V  qd S r9   r+   r]   r+   r+   r,   rA     s     z'read_aux_subset2inps.<locals>.<genexpr>zusing subset info from z<No lookup file found! Can not use --tight option without it.rD   r   )r   r   T)return_inverse
   ry   r{   zNo subset inputs found!)rN   r   r   r   r   	referencer   r   rU   r   r   rp   r   r1   get_lookup_filer    	Exceptionr|   r;   r   r   uniquewherebincountargmaxrt   rs   r   nanminnanmaxrr   )r5   Zref_atrrT   rS   Zatr_lutr   Zrg_lutZ	rg_uniqueZrg_posidx_rowidx_collatlonr+   r+   r,   read_aux_subset2inps  sN    
  
 r   c                 C   s<   t | }t|}|jD ] }td t|t||jd qd S )Nz------------------------------)r   )r6   r   r   r   r   varsr   )r4   r5   r   r+   r+   r,   main  s    
r   __main__r/   )N)N)N)N)r   sysr   numpyr   mintpy.utilsr   r   r   r   r1   r   r   Zmintpy.utils.arg_utilsr   r!   r"   r-   r6   rU   rp   rr   rx   r   r   r   r   r   r   r#   argvr+   r+   r+   r,   <module>	   s*   
1
%(<
  2
