Skip to content

Commit

Permalink
Merge pull request #1 from DHI-GRAS/repo-review
Browse files Browse the repository at this point in the history
Use the new pytporject.toml instead of the deprecated setup.py
  • Loading branch information
radosuav authored Jun 10, 2024
2 parents fb0988e + 7e7e38a commit fab151b
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 77 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: ruff_push
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- run: |
python -m pip install --upgrade pip
pip install ruff
- run: ruff check --output-format=github .
- name: If needed, commit ruff changes to a new pull request
if: failure()
run: |
ruff check --output-format=github --fix .
git config --global user.name github-actions
git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
git commit -am "fixup! Format Python code with ruff push"
git push --force origin HEAD:$GITHUB_REF
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,12 @@ zappa_settings.toml

_version.py
Makefile
tests/
tests/

test_data/fusion_results
test_data/S2/processed
test_data/S3/reprojected
test_data/S3/composites
test_data/S3/calibrated
test_data/S3/binning
test_data/S3/blurred
40 changes: 27 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,36 @@ as demonstrated by the example of Aarhus, Denmark in Spring 2021.
See run_efast.py for an example using data located in test_data folder.

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

- setuptools
- numpy
- scipy
- tqdm
- scikit-learn
- rasterio
- pandas
- ipdb
- astropy
- python-dateutil
- snap-graph (available through a Git repository)
### Try it out

1. Clone the repository to your local machine.
2. Navigate to the root directory of the repository in your terminal.
3. [OPTIONAL but recommended] Create a virtual environment: `python3.<your python version> -m venv .venv`
3. Install the package: `pip install -e .`
4. Run the example: `python run_efast.py`

### Installation
Install the package using pip:

```bash
pip install git+https://github.com/DHI-GRAS/efast.git
```

### Usage
```python
import pyefast

...
pyefast.fusion(
...
)
```

### Develop
1. Clone the repository to your local machine.
2. Navigate to the root directory of the repository in your terminal.
3. Run the following command to install the required packages: pip install -r requirements.txt
4. Run the following command to install the package: python setup.py install
3. [OPTIONAL but strongly recommended] Create a virtual environment: `python3.<your python version> -m venv .venv`
3. Install the package in dev mode: `pip install -e .[dev]`
1 change: 1 addition & 0 deletions pyefast/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .efast import fusion
5 changes: 3 additions & 2 deletions pyefast/efast.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@
"""

import os
from tqdm import tqdm

import numpy as np
import pandas as pd
import rasterio
import rasterio.windows
from scipy.interpolate import interp1d
import scipy.ndimage

from scipy.interpolate import interp1d
from tqdm import tqdm


def fusion(
pred_date,
Expand Down
32 changes: 19 additions & 13 deletions pyefast/s2_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@
"""

import re
from tqdm import tqdm
import xml.etree.ElementTree as ET

import numpy as np
import pyproj
import rasterio
import scipy as sp

from shapely.geometry import box
from shapely.ops import transform

from tqdm import tqdm

# Mapping of Sentinel-2 bands names to bands ids
BANDS_IDS = {
Expand All @@ -52,10 +52,9 @@
}


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

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

# Combine bands and mask
s2_image = np.zeros((len(bands), profile["height"], profile["width"]), "float32")
s2_image = np.zeros(
(len(bands), profile["height"], profile["width"]), "float32"
)
for i, band_path in enumerate(band_paths):
band = bands[i]
band_id = BANDS_IDS.get(band)
Expand All @@ -112,7 +114,9 @@ def extract_mask_s2_bands(input_dir,
s2_image[i] = data

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

# Update transform
s2_resolution = (s2_profile["transform"]*(1, 0))[0] - (s2_profile["transform"]*(0, 0))[0]
s2_resolution = (s2_profile["transform"] * (1, 0))[0] - (
s2_profile["transform"] * (0, 0)
)[0]
longitude_origin, latitude_origin = s2_profile["transform"] * (0, 0)
lr_transform = rasterio.Affine(
ratio * s2_resolution,
Expand Down Expand Up @@ -226,9 +232,9 @@ def get_wkt_footprint(dir_s2, crs="EPSG:4326"):
# Ensure footprint is in desired CRS
polygon = box(*bounds)
if image_crs != crs:
transformer = pyproj.Transformer.from_proj(pyproj.Proj(image_crs),
pyproj.Proj(crs),
always_xy=True)
transformer = pyproj.Transformer.from_proj(
pyproj.Proj(image_crs), pyproj.Proj(crs), always_xy=True
)
polygon = transform(transformer.transform, polygon)

# Step 4: Convert to WKT
Expand Down
29 changes: 13 additions & 16 deletions pyefast/s3_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,23 @@
@author: rmgu, pase
"""

from dateutil import rrule
from datetime import datetime
import os
import re
from tqdm import tqdm

from datetime import datetime

import astropy.convolution as ap
import numpy as np
import pandas as pd
import rasterio
from rasterio.vrt import WarpedVRT
from rasterio.enums import Resampling
from rasterio import shutil as rio_shutil
import scipy as sp

from dateutil import rrule
from rasterio import shutil as rio_shutil
from rasterio.enums import Resampling
from rasterio.vrt import WarpedVRT
from snap_graph.snap_graph import SnapGraph
from tqdm import tqdm


def binning_s3(
Expand Down Expand Up @@ -100,10 +101,9 @@ def binning_s3(
sen3_paths = [element for _, element in sorted(zip(date_strings, sen3_paths))]

for i, sen3_path in enumerate(sen3_paths):

output_path = os.path.join(
binning_dir,
sen3_path.stem+'.tif',
sen3_path.stem + ".tif",
)

variables = s3_bands.copy()
Expand Down Expand Up @@ -185,13 +185,7 @@ def binning_s3(


def produce_median_composite(
dir_s3,
composite_dir,
step=5,
mosaic_days=100,
s3_bands=None,
D=20,
sigma_doy=10
dir_s3, composite_dir, step=5, mosaic_days=100, s3_bands=None, D=20, sigma_doy=10
):
"""
Create weighted composites of Sentinel-3 images.
Expand Down Expand Up @@ -220,7 +214,10 @@ def produce_median_composite(
"""
sen3_paths = list(dir_s3.glob("S3*.tif"))
s3_dates = pd.to_datetime(
[re.match(".*__(\d{8})T.*\.tif", sen3_path.name).group(1) for sen3_path in sen3_paths]
[
re.match(".*__(\d{8})T.*\.tif", sen3_path.name).group(1)
for sen3_path in sen3_paths
]
)
sen3_paths = np.array(
[sen3_path for _, sen3_path in sorted(zip(s3_dates, sen3_paths))]
Expand Down
40 changes: 40 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[build-system]
requires = ["setuptools >= 61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "pyefast"
authors = [
{name = "sa", email = "[email protected]"},
]
description = "My package description"
readme = "README.md"
dynamic = ["version"]
dependencies = [
"python-dateutil",
"numpy",
"pandas",
"rasterio",
"scipy",
"tqdm",
"pyproj",
"shapely",
"astropy",
"snap-graph @ git+https://github.com/DHI-GRAS/snap-graph",

]

[project.optional-dependencies]
dev = [
"ruff",
]

[tool.setuptools.packages.find]
include = ["pyefast"]

[tool.ruff.lint]
select = ["I"]

[tool.ruff.lint.isort]
# Use a single line between direct and from import.
lines-between-types = 1
Loading

0 comments on commit fab151b

Please sign in to comment.