Skip to content

Commit fab151b

Browse files
authored
Merge pull request #1 from DHI-GRAS/repo-review
Use the new pytporject.toml instead of the deprecated setup.py
2 parents fb0988e + 7e7e38a commit fab151b

File tree

10 files changed

+161
-77
lines changed

10 files changed

+161
-77
lines changed

.github/workflows/ruff.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: ruff_push
2+
on: [push]
3+
jobs:
4+
build:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- uses: actions/checkout@v4
8+
- uses: actions/setup-python@v5
9+
- run: |
10+
python -m pip install --upgrade pip
11+
pip install ruff
12+
- run: ruff check --output-format=github .
13+
- name: If needed, commit ruff changes to a new pull request
14+
if: failure()
15+
run: |
16+
ruff check --output-format=github --fix .
17+
git config --global user.name github-actions
18+
git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'
19+
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
20+
git commit -am "fixup! Format Python code with ruff push"
21+
git push --force origin HEAD:$GITHUB_REF

.gitignore

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,12 @@ zappa_settings.toml
136136

137137
_version.py
138138
Makefile
139-
tests/
139+
tests/
140+
141+
test_data/fusion_results
142+
test_data/S2/processed
143+
test_data/S3/reprojected
144+
test_data/S3/composites
145+
test_data/S3/calibrated
146+
test_data/S3/binning
147+
test_data/S3/blurred

README.md

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,36 @@ as demonstrated by the example of Aarhus, Denmark in Spring 2021.
4040
See run_efast.py for an example using data located in test_data folder.
4141

4242
### Requirements
43+
* [python](https://www.python.org/getit/)
44+
* [esa-snap](https://step.esa.int/main/download/snap-download/) - needed for Sentinel-3 pre-processing only. Tested with version 9 and 10.
4345

44-
- setuptools
45-
- numpy
46-
- scipy
47-
- tqdm
48-
- scikit-learn
49-
- rasterio
50-
- pandas
51-
- ipdb
52-
- astropy
53-
- python-dateutil
54-
- snap-graph (available through a Git repository)
46+
### Try it out
47+
48+
1. Clone the repository to your local machine.
49+
2. Navigate to the root directory of the repository in your terminal.
50+
3. [OPTIONAL but recommended] Create a virtual environment: `python3.<your python version> -m venv .venv`
51+
3. Install the package: `pip install -e .`
52+
4. Run the example: `python run_efast.py`
5553

5654
### Installation
55+
Install the package using pip:
56+
57+
```bash
58+
pip install git+https://github.com/DHI-GRAS/efast.git
59+
```
60+
61+
### Usage
62+
```python
63+
import pyefast
64+
65+
...
66+
pyefast.fusion(
67+
...
68+
)
69+
```
5770

71+
### Develop
5872
1. Clone the repository to your local machine.
5973
2. Navigate to the root directory of the repository in your terminal.
60-
3. Run the following command to install the required packages: pip install -r requirements.txt
61-
4. Run the following command to install the package: python setup.py install
74+
3. [OPTIONAL but strongly recommended] Create a virtual environment: `python3.<your python version> -m venv .venv`
75+
3. Install the package in dev mode: `pip install -e .[dev]`

pyefast/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .efast import fusion

pyefast/efast.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@
2626
"""
2727

2828
import os
29-
from tqdm import tqdm
3029

3130
import numpy as np
3231
import pandas as pd
3332
import rasterio
3433
import rasterio.windows
35-
from scipy.interpolate import interp1d
3634
import scipy.ndimage
3735

36+
from scipy.interpolate import interp1d
37+
from tqdm import tqdm
38+
3839

3940
def fusion(
4041
pred_date,

pyefast/s2_processing.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,16 @@
2626
"""
2727

2828
import re
29-
from tqdm import tqdm
3029
import xml.etree.ElementTree as ET
3130

3231
import numpy as np
3332
import pyproj
3433
import rasterio
3534
import scipy as sp
35+
3636
from shapely.geometry import box
3737
from shapely.ops import transform
38-
38+
from tqdm import tqdm
3939

4040
# Mapping of Sentinel-2 bands names to bands ids
4141
BANDS_IDS = {
@@ -52,10 +52,9 @@
5252
}
5353

5454

55-
def extract_mask_s2_bands(input_dir,
56-
output_dir,
57-
bands=["B02", "B03", "B04", "B8A"],
58-
resolution=20):
55+
def extract_mask_s2_bands(
56+
input_dir, output_dir, bands=["B02", "B03", "B04", "B8A"], resolution=20
57+
):
5958
"""
6059
Extract specified Sentinel-2 bands from .SAFE file, mask clouds and shadows using the SLC mask
6160
and save to multi-band GeoTIFF file.
@@ -79,7 +78,8 @@ def extract_mask_s2_bands(input_dir,
7978
"""
8079
for p in input_dir.iterdir():
8180
band_paths = [
82-
list(p.glob(f"GRANULE/*/IMG_DATA/R{resolution}m/*{band}*.jp2"))[0] for band in bands
81+
list(p.glob(f"GRANULE/*/IMG_DATA/R{resolution}m/*{band}*.jp2"))[0]
82+
for band in bands
8383
]
8484

8585
# Find S2 BOA offsets
@@ -99,7 +99,9 @@ def extract_mask_s2_bands(input_dir,
9999
mask = (mask == 0) | (mask == 3) | (mask > 7)
100100

101101
# Combine bands and mask
102-
s2_image = np.zeros((len(bands), profile["height"], profile["width"]), "float32")
102+
s2_image = np.zeros(
103+
(len(bands), profile["height"], profile["width"]), "float32"
104+
)
103105
for i, band_path in enumerate(band_paths):
104106
band = bands[i]
105107
band_id = BANDS_IDS.get(band)
@@ -112,7 +114,9 @@ def extract_mask_s2_bands(input_dir,
112114
s2_image[i] = data
113115

114116
# Save file
115-
profile.update({"driver": "GTiff", "count": len(bands), "dtype": "float32", "nodata": 0})
117+
profile.update(
118+
{"driver": "GTiff", "count": len(bands), "dtype": "float32", "nodata": 0}
119+
)
116120
out_path = output_dir / f"{str(p.name).rstrip('.SAFE')}_REFL.tif"
117121
with rasterio.open(out_path, "w", **profile) as dst:
118122
dst.write(s2_image)
@@ -170,7 +174,9 @@ def distance_to_clouds(dir_s2, ratio=30, tolerance_percentage=0.05):
170174
distance_to_cloud = np.clip(distance_to_cloud, 0, 255)
171175

172176
# Update transform
173-
s2_resolution = (s2_profile["transform"]*(1, 0))[0] - (s2_profile["transform"]*(0, 0))[0]
177+
s2_resolution = (s2_profile["transform"] * (1, 0))[0] - (
178+
s2_profile["transform"] * (0, 0)
179+
)[0]
174180
longitude_origin, latitude_origin = s2_profile["transform"] * (0, 0)
175181
lr_transform = rasterio.Affine(
176182
ratio * s2_resolution,
@@ -226,9 +232,9 @@ def get_wkt_footprint(dir_s2, crs="EPSG:4326"):
226232
# Ensure footprint is in desired CRS
227233
polygon = box(*bounds)
228234
if image_crs != crs:
229-
transformer = pyproj.Transformer.from_proj(pyproj.Proj(image_crs),
230-
pyproj.Proj(crs),
231-
always_xy=True)
235+
transformer = pyproj.Transformer.from_proj(
236+
pyproj.Proj(image_crs), pyproj.Proj(crs), always_xy=True
237+
)
232238
polygon = transform(transformer.transform, polygon)
233239

234240
# Step 4: Convert to WKT

pyefast/s3_processing.py

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,23 @@
2525
@author: rmgu, pase
2626
"""
2727

28-
from dateutil import rrule
29-
from datetime import datetime
3028
import os
3129
import re
32-
from tqdm import tqdm
30+
31+
from datetime import datetime
3332

3433
import astropy.convolution as ap
3534
import numpy as np
3635
import pandas as pd
3736
import rasterio
38-
from rasterio.vrt import WarpedVRT
39-
from rasterio.enums import Resampling
40-
from rasterio import shutil as rio_shutil
4137
import scipy as sp
4238

39+
from dateutil import rrule
40+
from rasterio import shutil as rio_shutil
41+
from rasterio.enums import Resampling
42+
from rasterio.vrt import WarpedVRT
4343
from snap_graph.snap_graph import SnapGraph
44+
from tqdm import tqdm
4445

4546

4647
def binning_s3(
@@ -100,10 +101,9 @@ def binning_s3(
100101
sen3_paths = [element for _, element in sorted(zip(date_strings, sen3_paths))]
101102

102103
for i, sen3_path in enumerate(sen3_paths):
103-
104104
output_path = os.path.join(
105105
binning_dir,
106-
sen3_path.stem+'.tif',
106+
sen3_path.stem + ".tif",
107107
)
108108

109109
variables = s3_bands.copy()
@@ -185,13 +185,7 @@ def binning_s3(
185185

186186

187187
def produce_median_composite(
188-
dir_s3,
189-
composite_dir,
190-
step=5,
191-
mosaic_days=100,
192-
s3_bands=None,
193-
D=20,
194-
sigma_doy=10
188+
dir_s3, composite_dir, step=5, mosaic_days=100, s3_bands=None, D=20, sigma_doy=10
195189
):
196190
"""
197191
Create weighted composites of Sentinel-3 images.
@@ -220,7 +214,10 @@ def produce_median_composite(
220214
"""
221215
sen3_paths = list(dir_s3.glob("S3*.tif"))
222216
s3_dates = pd.to_datetime(
223-
[re.match(".*__(\d{8})T.*\.tif", sen3_path.name).group(1) for sen3_path in sen3_paths]
217+
[
218+
re.match(".*__(\d{8})T.*\.tif", sen3_path.name).group(1)
219+
for sen3_path in sen3_paths
220+
]
224221
)
225222
sen3_paths = np.array(
226223
[sen3_path for _, sen3_path in sorted(zip(s3_dates, sen3_paths))]

pyproject.toml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
[build-system]
2+
requires = ["setuptools >= 61.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "pyefast"
7+
authors = [
8+
{name = "sa", email = "[email protected]"},
9+
]
10+
description = "My package description"
11+
readme = "README.md"
12+
dynamic = ["version"]
13+
dependencies = [
14+
"python-dateutil",
15+
"numpy",
16+
"pandas",
17+
"rasterio",
18+
"scipy",
19+
"tqdm",
20+
"pyproj",
21+
"shapely",
22+
"astropy",
23+
"snap-graph @ git+https://github.com/DHI-GRAS/snap-graph",
24+
25+
]
26+
27+
[project.optional-dependencies]
28+
dev = [
29+
"ruff",
30+
]
31+
32+
[tool.setuptools.packages.find]
33+
include = ["pyefast"]
34+
35+
[tool.ruff.lint]
36+
select = ["I"]
37+
38+
[tool.ruff.lint.isort]
39+
# Use a single line between direct and from import.
40+
lines-between-types = 1

0 commit comments

Comments
 (0)