Skip to content

Commit a0be97e

Browse files
authored
Merge pull request #50 from ESA-PhiLab/develop
merge develop
2 parents d3a43f3 + c7e57b9 commit a0be97e

File tree

13 files changed

+94
-118
lines changed

13 files changed

+94
-118
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ __pycache__
66
htmlcov
77
.empty
88
.DS_Store
9-
ost/.DS_Store
9+
ost/.DS_Store
10+
build
11+
dist

Dockerfile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
FROM ubuntu:18.04
1+
FROM ubuntu:20.04
22

3-
LABEL maintainer="Petr Sevcik, EOX"
4-
LABEL OpenSARToolkit='0.11.1'
3+
LABEL maintainer="Andreas Vollrath, FAO"
4+
LABEL OpenSARToolkit='0.12.3'
55

66
# set work directory to home and download snap
77
WORKDIR /home/ost
88

99
# copy the snap installation config file into the container
10-
COPY snap8.varfile $HOME
10+
COPY snap.varfile $HOME
1111

1212
# update variables
1313
ENV OTB_VERSION="7.3.0" \
@@ -42,9 +42,9 @@ RUN alias python=python3 && \
4242
mkdir /home/ost/programs && \
4343
wget $SNAP_URL/$TBX && \
4444
chmod +x $TBX && \
45-
./$TBX -q -varfile snap7.varfile && \
45+
./$TBX -q -varfile snap.varfile && \
4646
rm $TBX && \
47-
rm snap7.varfile && \
47+
rm snap.varfile && \
4848
cd /home/ost/programs && \
4949
wget https://www.orfeo-toolbox.org/packages/${OTB} && \
5050
chmod +x $OTB && \

README.md

Lines changed: 21 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,23 @@ https://github.com/ESA-PhiLab/OST_Notebooks for getting started.
3232

3333
### Docker
3434

35-
A docker image is available from docker hub that contains the full package,
35+
**Update!**
36+
37+
Dockerhub is not permitting automatic builds. Therefore you need to
38+
build your own docker image using the DOCKERFIlE https://raw.githubusercontent.com/ESA-PhiLab/OpenSarToolkit/main/Dockerfile
39+
40+
The resulting docker image contains the full package,
3641
including ESA's Sentinel-1 Toolbox, Orfeo Toolbox, Jupyter Lab as well
37-
as the Open SAR Toolkit the tutorial notebooks.
42+
as the Open SAR Toolkit tutorial notebooks.
3843

3944
Docker installation is possible on various OS. Installation instructions can be
4045
found at https://docs.docker.com/install/
4146

4247
After docker is installed and running, launch the container with
43-
(adapt the path to the shared host folder):
48+
(adapt the path to the shared host folder and the name of the docke rimage at the very end):
4449

4550
```
46-
docker pull buddyvolly/opensartoolkit
47-
docker run -it -p 8888:8888 -v /shared/folder/on/host:/home/ost/shared buddyvolly/opensartoolkit
51+
docker run -it -p 8888:8888 -v /shared/folder/on/host:/home/ost/shared docker/image
4852
```
4953

5054
The docker image automatically executes the jupyter lab and runs it on
@@ -68,6 +72,8 @@ If you install SNAP into the standard directory, OST should have no problems
6872
to find the SNAP command line executable. Otherwise you need to define the path
6973
to the gpt file on your own during processing.
7074

75+
**Make sure to use SNAP 8 with the latest updates installed.**
76+
7177
##### Orfeo Toolbox
7278

7379
If you want to create mosaics between different swaths, OST will rely on the
@@ -78,79 +84,25 @@ https://www.orfeo-toolbox.org/download/
7884
Make sure that the Orfeo bin folder is within your PATH variable to allow
7985
execution from command line.
8086

81-
#### OST installation
82-
83-
OST is developed under Ubuntu 18.04 OS in python 3.6. It has not been tested
84-
much on other OS and python versions, but should in principle work on any OS
85-
and any python version >= 3.5.
86-
87-
##### Ubuntu/Debian Linux (using pip)
88-
89-
Before installation of OST, run the following line on the terminal to
90-
install further dependencies:
91-
92-
```
93-
sudo apt install python3-pip git libgdal-dev python3-gdal libspatialindex-dev nodejs npm
94-
```
95-
96-
then install OST as a global package (for all users, admin rights needed):
87+
##### Further dependencies (libs etc)
9788

89+
Ubuntu 18.04 and later:
9890
```
99-
sudo pip3 install git+https://github.com/ESA-PhiLab/OpenSarToolkit.git
91+
sudo apt install python3-pip git libgdal-dev python3-gdal libspatialindex-dev nodejs npm libgfortran5
10092
```
10193

102-
or as local package within your home folder (no admin rights needed):
103-
104-
```
105-
pip3 install --user git+https://github.com/ESA-PhiLab/OpenSarToolkit.git
106-
```
94+
Any Operating system using (mini)conda https://www.anaconda.com/:
10795

108-
run those commands to enable the correct display of progress bars
10996
```
110-
sudo pip3 install jupyterlab
111-
# this is needed for the progress bar when downloading
112-
sudo jupyter-labextension install @jupyter-widgets/jupyterlab-manager
113-
sudo jupyter nbextension enable --py widgetsnbextension
114-
```
115-
116-
##### Mac OS (using homebrew/pip)
117-
118-
If not already installed, install homebrew as explained on https://brew.sh
119-
120-
After installation of homebrew, open the terminal and install
121-
further dependecies:
122-
123-
```
124-
brew install python3 gdal2 gdal2-python git
125-
```
126-
127-
then install OST with python pip:
128-
```
129-
pip3 install git+https://github.com/ESA-PhiLab/OpenSarToolkit.git
130-
131-
# this is needed for the progress bar when downloading data
132-
jupyter labextension install @jupyter-widgets/jupyterlab-manager
133-
jupyter nbextension enable --py widgetsnbextension
97+
conda install pip gdal jupyter jupyterlab git matplotlib numpy rasterio imageio rtree geopandas fiona shapely matplotlib descartes tqdm scipy joblib retrying pytest pytest-cov nodejs
13498
```
13599

136-
##### Conda Installation (Windows, Mac, Linux)
137-
138-
Follow the installation instructions for conda (Miniconda is sufficient) at:
139-
https://docs.conda.io/projects/conda/en/latest/user-guide/install/
140-
141-
Then run the conda command to install OST's dependencies:
142-
```
143-
conda install pip gdal jupyter jupyterlab git matplotlib numpy rasterio imageio rtree geopandas fiona shapely matplotlib descartes tqdm scipy joblib retrying pytest pytest-cov nodejs
100+
#### OST installation
144101

145-
# this is needed for the progress bar when downloading
146-
jupyter labextension install @jupyter-widgets/jupyterlab-manager
147-
jupyter nbextension enable --py widgetsnbextension
148-
```
102+
You can use then use pip to install Open SAR Toolkit:
149103

150-
Finally get the OST by using pip
151-
(we will work in future on a dedicated conda package for OST).
152104
```
153-
pip install git+https://github.com/ESA-PhiLab/OpenSarToolkit.git
105+
pip install opensartoolkit
154106
```
155107

156108

@@ -206,5 +158,6 @@ that are developed in parallel to this core package and should help to get start
206158

207159
## Author
208160

209-
* Andreas Vollrath, ESA
161+
* Andreas Vollrath, FAO (ex-ESA philab)
210162
* Petr Sevcik, EOX
163+
* James Wheeler, ESA philab

ost/Project.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
# ------ bug of rasterio --------
55
import os
6+
67
if "GDAL_DATA" in list(os.environ.keys()):
78
del os.environ["GDAL_DATA"]
89
if "PROJ_LIB" in list(os.environ.keys()):
@@ -69,7 +70,7 @@ def __init__(
6970
logger.info('Project directory already exists. '
7071
'No data has been deleted at this point but '
7172
'make sure you really want to use this folder.')
72-
73+
7374
# define project sub-directories if not set, and create folders
7475
self.download_dir = self.project_dir.joinpath('download')
7576
self.download_dir.mkdir(parents=True, exist_ok=True)
@@ -366,7 +367,7 @@ def download(self, inventory_df, mirror=None, concurrent=2,
366367
download_df = inventory_df[inventory_df.download_path == 'None']
367368

368369
# to download or not ot download - that is here the question
369-
if not download_df.any().any():
370+
if download_df.empty:
370371
logger.info('All scenes are ready for being processed.')
371372
else:
372373
logger.info('One or more scene(s) need(s) to be downloaded.')
@@ -617,7 +618,6 @@ def pre_download_srtm(self):
617618
logger.info('Pre-downloading SRTM tiles')
618619
srtm.download_srtm(self.aoi)
619620

620-
621621
def bursts_to_ards(
622622
self,
623623
timeseries=False,
@@ -712,13 +712,13 @@ def bursts_to_ards(
712712
if overwrite:
713713
logger.info('Deleting processing folder to start from scratch')
714714
h.remove_folder_content(self.config_dict['processing_dir'])
715-
715+
716716
# --------------------------------------------
717717
# 5 set resolution to degree
718718
# self.ard_parameters['resolution'] = h.resolution_in_degree(
719719
# self.center_lat, self.ard_parameters['resolution'])
720720

721-
if self.config_dict['max_workers'] > 1:
721+
if self.config_dict['max_workers'] > 1 and self.ard_parameters['single_ARD']['dem']['dem_name'] == 'SRTM 1Sec HGT':
722722
self.pre_download_srtm()
723723

724724
# --------------------------------------------

ost/generic/common_wrappers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def terrain_correction(infile, outfile, logfile, config_dict):
192192
projection = f"AUTO:{dem_dict['out_projection']}"
193193
# epsg codes
194194
elif int(dem_dict['out_projection']) == 4326:
195-
projection = CRS.from_epsg(4326).to_wkt()
195+
projection = 'WGS84(DD)'
196196
else:
197197
projection = f"EPSG:{dem_dict['out_projection']}"
198198

@@ -277,7 +277,7 @@ def ls_mask(infile, outfile, logfile, config_dict):
277277
projection = f"AUTO:{dem_dict['out_projection']}"
278278
# epsg codes
279279
elif int(dem_dict['out_projection']) == 4326:
280-
projection = CRS.from_epsg(4326).to_wkt()
280+
projection = 'WGS84(DD)'
281281
else:
282282
projection = f"EPSG:{dem_dict['out_projection']}"
283283

ost/helpers/db.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def shpGeom2pg(self, aoi, tablename):
151151
feature = layer.GetFeature(i)
152152
wkt = feature.GetGeometryRef().ExportToWkt()
153153

154-
if inProj4 is not '+proj=longlat +datum=WGS84 +no_defs':
154+
if inProj4 != '+proj=longlat +datum=WGS84 +no_defs':
155155
wkt = reproject_geometry(wkt, inProj4, 4326)
156156

157157
wkt = 'St_GeomFromText(\'{}\', 4326)'.format(wkt)

ost/helpers/scihub.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ def check_connection(uname, pword,
198198

199199
# we use some random url for checking (also for czech mirror)
200200
url = (
201-
f'{base_url}/odata/v1/Products?'
202-
'$select=Id&$filter=substringof(%27_20200714T165921_%27,Name)'
201+
f'{base_url}/odata/v1/Products('
202+
'\'8f30a536-c01c-4ef4-ac74-be3378dc44c4\')/$value'
203203
)
204204

205205
response = requests.get(url, auth=(uname, pword), stream=True)

ost/helpers/srtm.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,13 @@ def download_srtm(aoi):
9595
warnings.filterwarnings(
9696
'ignore', 'Geometry is in a geographic CRS', UserWarning
9797
)
98-
srtm = gpd.read_file(
99-
OST_ROOT.joinpath('aux/srtm1sectiles.gpkg')
100-
)
98+
99+
srtm = gpd.read_file(OST_ROOT.joinpath('aux/srtm1sectiles.gpkg'))
101100

102101
aoi_gdf = vec.wkt_to_gdf(aoi)
103102
aoi_gdf['geometry'] = aoi_gdf.geometry.buffer(1)
104103
overlap_df = gpd.overlay(srtm, aoi_gdf, how='intersection')
104+
105105
iter_list = []
106106
for file in overlap_df.url.values:
107107
iter_list.append(file)

ost/helpers/vector.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import os
22
import json
3-
from functools import partial
43
from pathlib import Path
54

65
import pyproj
6+
from pyproj.crs import ProjectedCRS
7+
from pyproj.crs.coordinate_operation import AzumuthalEquidistantConversion
78
import geopandas as gpd
89
import logging
910

@@ -171,7 +172,7 @@ def reproject_geometry(geom, inproj4, out_epsg):
171172
return geom
172173

173174

174-
def geodesic_point_buffer(lat, lon, meters, envelope=False):
175+
def geodesic_point_buffer(lon, lat, meters, envelope=False):
175176
"""
176177
177178
:param lat:
@@ -181,23 +182,24 @@ def geodesic_point_buffer(lat, lon, meters, envelope=False):
181182
:return:
182183
"""
183184

184-
# get WGS 84 proj
185-
proj_wgs84 = pyproj.Proj('epsg:4326')
186-
187-
# Azimuthal equidistant projection
188-
aeqd_proj = '+proj=aeqd +lat_0={lat} +lon_0={lon} +x_0=0 +y_0=0'
189-
project = partial(
190-
pyproj.transform,
191-
pyproj.Proj(aeqd_proj.format(lat=lat, lon=lon)),
192-
proj_wgs84
185+
proj_crs = ProjectedCRS(
186+
conversion=AzumuthalEquidistantConversion(float(lat), float(lon))
193187
)
194188

189+
proj_wgs84 = pyproj.Proj('EPSG:4326')
190+
191+
Trans = pyproj.Transformer.from_proj(
192+
proj_crs,
193+
proj_wgs84,
194+
always_xy=True
195+
).transform
196+
195197
buf = Point(0, 0).buffer(meters) # distance in metres
196198

197199
if envelope is True:
198-
geom = Polygon(transform(project, buf).exterior.coords[:]).envelope
200+
geom = Polygon(transform(Trans, buf).exterior.coords[:]).envelope
199201
else:
200-
geom = Polygon(transform(project, buf).exterior.coords[:])
202+
geom = Polygon(transform(Trans, buf).exterior.coords[:])
201203

202204
return geom.wkt
203205

@@ -240,7 +242,7 @@ def latlon_to_wkt(
240242
aoi_wkt = aoi_geom.to_wkt()
241243

242244
elif buffer_meter:
243-
aoi_wkt = geodesic_point_buffer(lat, lon, buffer_meter, envelope)
245+
aoi_wkt = geodesic_point_buffer(lon, lat, buffer_meter, envelope)
244246

245247
return aoi_wkt
246248

ost/s1/burst_batch.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def _create_timeseries(burst_gdf, config_file):
309309
product, product_name = list(pr)
310310

311311
# take care of H-A-Alpha naming for file search
312-
if pol in ['Alpha', 'Entropy', 'Anisotropy'] and product is 'pol':
312+
if pol in ['Alpha', 'Entropy', 'Anisotropy'] and product == 'pol':
313313
list_of_files = sorted(
314314
list(burst_dir.glob(f'20*/*data*/*{pol}*img')))
315315
else:
@@ -654,7 +654,7 @@ def mosaic_timescan(burst_inventory, config_file):
654654

655655
if 'harmonics' in metrics:
656656
metrics.remove('harmonics')
657-
metrics.extend(['amplitude', 'phase', 'residuals'])
657+
metrics.extend(['amplitude', 'phase', 'residuals', 'model_mean'])
658658

659659
if 'percentiles' in metrics:
660660
metrics.remove('percentiles')

0 commit comments

Comments
 (0)