Download this notebook from github.
XSAR example¶
open a dataset with xsar.open_dataset
[1]:
import xsar
import os
import numpy as np
[2]:
# get test file. You can replace with an path to other SAFE
filename = xsar.get_test_file('S1A_IW_GRDH_1SDV_20170907T103020_20170907T103045_018268_01EB76_Z010.SAFE')
Open a dataset with a xsar.Sentinel1Meta object¶
A xsar.Sentinel1Meta object handles all attributes and methods that can’t be embdeded in a xarray.Dataset
object. It can also replace a filename in xarray.open_dataset
When using it in a notebook, it also have an html representation.
[3]:
sar_meta = xsar.Sentinel1Meta(filename)
sar_meta
[3]:
Single dataset
SENTINEL1_DS:S1A_IW_GRDH_1SDV_20170907T103020_20170907T103045_018268_01EB76_Z010.SAFE:IW | |||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
sar_meta
object is an xsar.Sentinel1Meta object that can be given to xarray.open_dataset
or xsar.Sentinel1Dataset , as if it was a filename:
[4]:
sar_ds = xsar.Sentinel1Dataset(sar_meta)
sar_ds
[4]:
full dataset coverage
SENTINEL1_DS:S1A_IW_GRDH_1SDV_20170907T103020_20170907T103045_018268_01EB76_Z010.SAFE:IW | |||||
---|---|---|---|---|---|
|
Open a dataset at lower resolution¶
We can use sar_meta
properties to compute the pixel count we need to average to get a resolution of 200*200 meters
[5]:
resolution = {'atrack' : int(np.round(200 / sar_meta.pixel_atrack_m)), 'xtrack': int(np.round(200 / sar_meta.pixel_xtrack_m))}
resolution
[5]:
{'atrack': 20, 'xtrack': 20}
Then we can instantiate a xsar.Sentinel1Dataset, with the given resolution. Note that the above pixel size has changed.
[6]:
sar_ds = xsar.Sentinel1Dataset(sar_meta, resolution=resolution)
sar_ds
[6]:
full dataset coverage
SENTINEL1_DS:S1A_IW_GRDH_1SDV_20170907T103020_20170907T103045_018268_01EB76_Z010.SAFE:IW | |||||
---|---|---|---|---|---|
|
Extract a sub image of 10*10km around a lon/lat point¶
Convert (lon,lat) to (atrack, xtrack)¶
we can use sar_meta.ll2coords to convert (lon,lat) to (atrack, xtrack):
[7]:
# from a shapely object
point_lonlat = sar_meta.footprint.centroid
point_coords = sar_meta.ll2coords(point_lonlat.x, point_lonlat.y)
point_coords
[7]:
(8421.566059451987, 12589.902956209728)
The result is floating, because it is the position inside the pixel. If real indexes from existing dataset is needed, you’ll have to use sar_ds.ll2coords Result will be the nearest (atrack, xtrack) in the dataset
[8]:
point_coords = sar_ds.ll2coords(point_lonlat.x, point_lonlat.y)
point_coords
[8]:
(8430.0, 12590.0)
Extract the sub-image¶
[9]:
box_size = 10000 # 10km
dist = {'atrack' : int(np.round(box_size / 2 / sar_meta.pixel_atrack_m)), 'xtrack': int(np.round(box_size / 2 / sar_meta.pixel_xtrack_m))}
dist
[9]:
{'atrack': 490, 'xtrack': 500}
The xarray/dask dataset is available as a property : sar_ds.dataset. This attribute can be set to a new values, so the attributes like pixel spacing and coverage are correctly recomputed:
[10]:
# select 10*10 km around point_coords
sar_ds.dataset = sar_ds.dataset.sel(atrack=slice(point_coords[0] - dist['atrack'], point_coords[0] + dist['atrack']), xtrack=slice(point_coords[1] - dist['xtrack'], point_coords[1] + dist['xtrack']))
sar_ds
[10]:
dataset slice
SENTINEL1_DS:S1A_IW_GRDH_1SDV_20170907T103020_20170907T103045_018268_01EB76_Z010.SAFE:IW | |||||
---|---|---|---|---|---|
|
[11]:
sar_ds.dataset
[11]:
<xarray.Dataset> Dimensions: (atrack: 49, pol: 2, xtrack: 51) Coordinates: * pol (pol) object 'VV' 'VH' * atrack (atrack) float64 7.95e+03 7.97e+03 ... 8.89e+03 8.91e+03 * xtrack (xtrack) float64 1.209e+04 1.211e+04 ... 1.307e+04 1.309e+04 Data variables: (12/14) digital_number (pol, atrack, xtrack) uint16 dask.array<chunksize=(1, 49, 51), meta=np.ndarray> time (atrack) datetime64[ns] 2017-09-07T10:30:32.793691648 ...... longitude (atrack, xtrack) float32 dask.array<chunksize=(49, 51), meta=np.ndarray> latitude (atrack, xtrack) float32 dask.array<chunksize=(49, 51), meta=np.ndarray> land_mask (atrack, xtrack) int8 dask.array<chunksize=(49, 51), meta=np.ndarray> ground_heading (atrack, xtrack) float32 dask.array<chunksize=(49, 51), meta=np.ndarray> ... ... sigma0_raw (pol, atrack, xtrack) float64 dask.array<chunksize=(1, 49, 51), meta=np.ndarray> nesz (pol, atrack, xtrack) float64 dask.array<chunksize=(1, 49, 51), meta=np.ndarray> gamma0_raw (pol, atrack, xtrack) float64 dask.array<chunksize=(1, 49, 51), meta=np.ndarray> negz (pol, atrack, xtrack) float64 dask.array<chunksize=(1, 49, 51), meta=np.ndarray> sigma0 (pol, atrack, xtrack) float64 dask.array<chunksize=(1, 49, 51), meta=np.ndarray> gamma0 (pol, atrack, xtrack) float64 dask.array<chunksize=(1, 49, 51), meta=np.ndarray> Attributes: (12/14) ipf: 2.84 platform: SENTINEL-1A swath: IW product: GRDH pols: VV VH name: SENTINEL1_DS:/tmp/S1A_IW_GRDH_1SDV_20170907T103020_201... ... ... footprint: POLYGON ((-69.12627509838202 20.21794031159714, -69.22... coverage: 9km * 10km (atrack * xtrack ) pixel_atrack_m: 203.5819198789976 pixel_xtrack_m: 199.7376700425335 orbit_pass: Descending platform_heading: -167.7668824808032
- atrack: 49
- pol: 2
- xtrack: 51
- pol(pol)object'VV' 'VH'
array(['VV', 'VH'], dtype=object)
- atrack(atrack)float647.95e+03 7.97e+03 ... 8.91e+03
array([7950., 7970., 7990., 8010., 8030., 8050., 8070., 8090., 8110., 8130., 8150., 8170., 8190., 8210., 8230., 8250., 8270., 8290., 8310., 8330., 8350., 8370., 8390., 8410., 8430., 8450., 8470., 8490., 8510., 8530., 8550., 8570., 8590., 8610., 8630., 8650., 8670., 8690., 8710., 8730., 8750., 8770., 8790., 8810., 8830., 8850., 8870., 8890., 8910.])
- xtrack(xtrack)float641.209e+04 1.211e+04 ... 1.309e+04
array([12090., 12110., 12130., 12150., 12170., 12190., 12210., 12230., 12250., 12270., 12290., 12310., 12330., 12350., 12370., 12390., 12410., 12430., 12450., 12470., 12490., 12510., 12530., 12550., 12570., 12590., 12610., 12630., 12650., 12670., 12690., 12710., 12730., 12750., 12770., 12790., 12810., 12830., 12850., 12870., 12890., 12910., 12930., 12950., 12970., 12990., 13010., 13030., 13050., 13070., 13090.])
- digital_number(pol, atrack, xtrack)uint16dask.array<chunksize=(1, 49, 51), meta=np.ndarray>
Array Chunk Bytes 9.76 kiB 4.88 kiB Shape (2, 49, 51) (1, 49, 51) Count 8 Tasks 2 Chunks Type uint16 numpy.ndarray - time(atrack)datetime64[ns]2017-09-07T10:30:32.793691648 .....
array(['2017-09-07T10:30:32.793691648', '2017-09-07T10:30:32.823558656', '2017-09-07T10:30:32.853425920', '2017-09-07T10:30:32.883293184', '2017-09-07T10:30:32.913160448', '2017-09-07T10:30:32.943027456', '2017-09-07T10:30:32.972894720', '2017-09-07T10:30:33.002761984', '2017-09-07T10:30:33.032629248', '2017-09-07T10:30:33.062496512', '2017-09-07T10:30:33.092363520', '2017-09-07T10:30:33.122230784', '2017-09-07T10:30:33.152098048', '2017-09-07T10:30:33.181965312', '2017-09-07T10:30:33.211832576', '2017-09-07T10:30:33.241699584', '2017-09-07T10:30:33.271566848', '2017-09-07T10:30:33.301434112', '2017-09-07T10:30:33.331301376', '2017-09-07T10:30:33.361168640', '2017-09-07T10:30:33.391035648', '2017-09-07T10:30:33.420902912', '2017-09-07T10:30:33.450770176', '2017-09-07T10:30:33.480637440', '2017-09-07T10:30:33.510504448', '2017-09-07T10:30:33.540371712', '2017-09-07T10:30:33.570238976', '2017-09-07T10:30:33.600106240', '2017-09-07T10:30:33.629973504', '2017-09-07T10:30:33.659840512', '2017-09-07T10:30:33.689707776', '2017-09-07T10:30:33.719575040', '2017-09-07T10:30:33.749442304', '2017-09-07T10:30:33.779309568', '2017-09-07T10:30:33.809176576', '2017-09-07T10:30:33.839043840', '2017-09-07T10:30:33.868911104', '2017-09-07T10:30:33.898778368', '2017-09-07T10:30:33.928645632', '2017-09-07T10:30:33.958512640', '2017-09-07T10:30:33.988379904', '2017-09-07T10:30:34.018247168', '2017-09-07T10:30:34.048114432', '2017-09-07T10:30:34.077981440', '2017-09-07T10:30:34.107848704', '2017-09-07T10:30:34.137715968', '2017-09-07T10:30:34.167583232', '2017-09-07T10:30:34.197450496', '2017-09-07T10:30:34.227317504'], dtype='datetime64[ns]')
- longitude(atrack, xtrack)float32dask.array<chunksize=(49, 51), meta=np.ndarray>
Array Chunk Bytes 9.76 kiB 9.76 kiB Shape (49, 51) (49, 51) Count 7 Tasks 1 Chunks Type float32 numpy.ndarray - latitude(atrack, xtrack)float32dask.array<chunksize=(49, 51), meta=np.ndarray>
Array Chunk Bytes 9.76 kiB 9.76 kiB Shape (49, 51) (49, 51) Count 7 Tasks 1 Chunks Type float32 numpy.ndarray - land_mask(atrack, xtrack)int8dask.array<chunksize=(49, 51), meta=np.ndarray>
Array Chunk Bytes 2.44 kiB 2.44 kiB Shape (49, 51) (49, 51) Count 4 Tasks 1 Chunks Type int8 numpy.ndarray - ground_heading(atrack, xtrack)float32dask.array<chunksize=(49, 51), meta=np.ndarray>
Array Chunk Bytes 9.76 kiB 9.76 kiB Shape (49, 51) (49, 51) Count 5 Tasks 1 Chunks Type float32 numpy.ndarray - elevation(atrack, xtrack)float32dask.array<chunksize=(49, 51), meta=np.ndarray>
Array Chunk Bytes 9.76 kiB 9.76 kiB Shape (49, 51) (49, 51) Count 6 Tasks 1 Chunks Type float32 numpy.ndarray - incidence(atrack, xtrack)float32dask.array<chunksize=(49, 51), meta=np.ndarray>
Array Chunk Bytes 9.76 kiB 9.76 kiB Shape (49, 51) (49, 51) Count 6 Tasks 1 Chunks Type float32 numpy.ndarray - sigma0_raw(pol, atrack, xtrack)float64dask.array<chunksize=(1, 49, 51), meta=np.ndarray>
Array Chunk Bytes 39.05 kiB 19.52 kiB Shape (2, 49, 51) (1, 49, 51) Count 32 Tasks 2 Chunks Type float64 numpy.ndarray - nesz(pol, atrack, xtrack)float64dask.array<chunksize=(1, 49, 51), meta=np.ndarray>
Array Chunk Bytes 39.05 kiB 19.52 kiB Shape (2, 49, 51) (1, 49, 51) Count 41 Tasks 2 Chunks Type float64 numpy.ndarray - gamma0_raw(pol, atrack, xtrack)float64dask.array<chunksize=(1, 49, 51), meta=np.ndarray>
Array Chunk Bytes 39.05 kiB 19.52 kiB Shape (2, 49, 51) (1, 49, 51) Count 32 Tasks 2 Chunks Type float64 numpy.ndarray - negz(pol, atrack, xtrack)float64dask.array<chunksize=(1, 49, 51), meta=np.ndarray>
Array Chunk Bytes 39.05 kiB 19.52 kiB Shape (2, 49, 51) (1, 49, 51) Count 41 Tasks 2 Chunks Type float64 numpy.ndarray - sigma0(pol, atrack, xtrack)float64dask.array<chunksize=(1, 49, 51), meta=np.ndarray>
Array Chunk Bytes 39.05 kiB 19.52 kiB Shape (2, 49, 51) (1, 49, 51) Count 61 Tasks 2 Chunks Type float64 numpy.ndarray - gamma0(pol, atrack, xtrack)float64dask.array<chunksize=(1, 49, 51), meta=np.ndarray>
Array Chunk Bytes 39.05 kiB 19.52 kiB Shape (2, 49, 51) (1, 49, 51) Count 61 Tasks 2 Chunks Type float64 numpy.ndarray
- ipf :
- 2.84
- platform :
- SENTINEL-1A
- swath :
- IW
- product :
- GRDH
- pols :
- VV VH
- name :
- SENTINEL1_DS:/tmp/S1A_IW_GRDH_1SDV_20170907T103020_20170907T103045_018268_01EB76_Z010.SAFE:IW
- start_date :
- 2017-09-07 10:30:20.936409
- stop_date :
- 2017-09-07 10:30:45.935264
- footprint :
- POLYGON ((-69.12627509838202 20.21794031159714, -69.22217959996208 20.23509299694786, -69.23994091576878 20.14694340052122, -69.14409175642585 20.12978289801671, -69.12627509838202 20.21794031159714))
- coverage :
- 9km * 10km (atrack * xtrack )
- pixel_atrack_m :
- 203.5819198789976
- pixel_xtrack_m :
- 199.7376700425335
- orbit_pass :
- Descending
- platform_heading :
- -167.7668824808032