Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions .github/workflows/build_and_test_app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ jobs:
- name: install quality deps
run: |
pip install pylint mccabe
- name: code quality
- name: Run Pylint
shell: bash -l {0}
run: |
pylint --recursive=y --disable=all --fail-under=10 --enable=too-many-statements,too-many-nested-blocks .
- name: Run McCabe Complexity Check
shell: bash -l {0}
run: |
pylint --disable=all --fail-under=10 --enable=too-many-statements --max-statements=100 .
pylint --disable=all --fail-under=10 --enable=too-many-nested-blocks .
./continuous_integration/scripts/check_mccabe_complexity.sh 25 .
test:
runs-on: ubuntu-22.04
Expand All @@ -46,7 +49,6 @@ jobs:
if [ -f docker/requirements.txt ]; then pip install -r docker/requirements.txt; fi
- name: pytest
run: |
cd tests
export CMAKE_PREFIX_PATH=/opt/otb
export PYTHONPATH=/opt/otb/lib/python3/dist-packages:/opt/otb/lib/otb/python
export GDAL_DRIVER_PATH=disable
Expand All @@ -57,5 +59,13 @@ jobs:
export OTB_APPLICATION_PATH=/opt/otb/lib/otb/applications
export OTB_INSTALL_DIR=/opt/otb
export LC_NUMERIC=C

pytest -s --cov-fail-under=65

pytest --cov=tests --cov-report=xml:.ci-reports-alcd/coverage_alcd.xml --cov-report html:cov_html_alcd --cov-report=term --junitxml=pytest-results-alcd.xml
- name: Upload Coverage Report
uses: actions/upload-artifact@v4
with:
name: coverage-report-alcd
path: |
.ci-reports-alcd/
cov_html_alcd/
pytest-results-alcd.xml
Binary file removed ALCD_user_manual.pdf
Binary file not shown.
108 changes: 62 additions & 46 deletions L1C_band_composition.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,49 +419,21 @@ def create_image_compositions(global_parameters, location, paths_parameters, cur

# Create new indices if needed
new_indices = global_parameters["features"]["special_indices"]
for indice in new_indices:
out_tif = op.join(out_dir_bands, (indice + '.tif'))
create_specific_indices(bands_dir, out_tif, indice_name=indice, resolution=resolution)
additional_bands.append(str(out_tif))
create_new_indices(additional_bands, bands_dir, new_indices, out_dir_bands, resolution)

# Create the ratios
ratios = create_ratio_bands(global_parameters, bands_dir, out_dir_bands, resolution=60)
additional_bands.extend(ratios)

use_DTM = str2bool(global_parameters["features"]["DTM"])
if use_DTM:
# Append the DTM model
out_dtm = op.join(out_dir_bands, ('DTM.tif'))
# try to append it. If an error occurs, the DTM probably does not exist
# and we will therefore skip this band
try:
dtm_addition(location, out_dtm, resolution=resolution)
additional_bands.append(str(out_dtm))
except:
print('ERROR : THE DTM DOES NOT EXIST !!!')
use_dtm(additional_bands, global_parameters, location, out_dir_bands, resolution)

create_textures = str2bool(global_parameters["features"]["textures"])
# Create the texture features
if create_textures:
band_used_for_contours = 2
in_tif = glob.glob(
op.join(bands_dir, '*{}*{:02}.jp2'.format(band_prefix, band_used_for_contours)))[0]
in_channel = 1

out_tif = op.join(out_dir_bands, 'density_contours.tif')
create_contours_density(in_tif, in_channel, out_tif, radius=3)
additional_bands.append(str(out_tif))
out_tif = op.join(out_dir_bands, 'variation_coeff.tif')
create_variation_coeff(in_tif, in_channel, out_tif, radius=3)
additional_bands.append(str(out_tif))
create_texture_feat(additional_bands, band_prefix, bands_dir, out_dir_bands)

# Create time difference features
bands_num = [int(band) for band in global_parameters["features"]["time_difference_bands"]]
out_dir_bands = op.join(global_parameters["user_choices"]["main_dir"], 'Intermediate')
for band_num in bands_num:
out_tif = op.join(out_dir_bands, ('time_' + str(band_num) + '.tif'))
create_time_difference_band(global_parameters, paths_parameters, band_num, out_tif, resolution=resolution)
additional_bands.append(str(out_tif))
time_diff_feat(additional_bands, global_parameters, paths_parameters, resolution)

# --- Create the main TIF with low resolution
# create intermediate resolution files
Expand Down Expand Up @@ -501,10 +473,7 @@ def create_image_compositions(global_parameters, location, paths_parameters, cur
new_indices = ['NDVI', 'NDWI']
out_dir_bands = op.join(global_parameters["user_choices"]["main_dir"], 'Intermediate')
additional_bands = []
for indice in new_indices:
out_tif = op.join(out_dir_bands, (indice + '.tif'))
create_specific_indices(bands_dir, out_tif, indice_name=indice, resolution=resolution)
additional_bands.append(str(out_tif))
create_new_indices(additional_bands, bands_dir, new_indices, out_dir_bands, resolution)

# create intermediate resolution files
intermediate_bands_dir = op.join(
Expand All @@ -513,15 +482,8 @@ def create_image_compositions(global_parameters, location, paths_parameters, cur
pixelresY = resolution

# The bands to put into the heavy file
bands_num = [2, 3, 4, 10]

intermediate_sizes_paths = []
for band in bands_num:
in_band = str(op.join(bands_dir, band_prefix) + '{:02d}'.format(band)+'.jp2')
out_band = op.join(intermediate_bands_dir, op.basename(in_band)[0:-4]+'.tif')

resize_band(in_band, out_band, pixelresX, pixelresY)
intermediate_sizes_paths.append(out_band)
intermediate_sizes_paths = put_band_heavy_tif(band_prefix, bands_dir, intermediate_bands_dir,
intermediate_sizes_paths, pixelresX, pixelresY)

out_heavy_tif = op.join(global_parameters["user_choices"]["main_dir"], 'In_data',
'Image', global_parameters["user_choices"]["raw_img"])[0:-4]+'_H.tif'
Expand All @@ -531,7 +493,6 @@ def create_image_compositions(global_parameters, location, paths_parameters, cur
compose_bands_heavy(intermediate_sizes_paths, str(out_heavy_tif))

if "user_function" in list(global_parameters["user_choices"].keys()) and global_parameters["user_choices"]["user_function"] != None:
print('ENTERED')
user_process(raw_img = out_all_bands_tif,
main_dir = global_parameters["user_choices"]["main_dir"],
module_path = global_parameters["user_choices"]["user_module"],
Expand All @@ -541,6 +502,61 @@ def create_image_compositions(global_parameters, location, paths_parameters, cur
return


def put_band_heavy_tif(band_prefix, bands_dir, intermediate_bands_dir, intermediate_sizes_paths, pixelresX, pixelresY):
bands_num = [2, 3, 4, 10]
intermediate_sizes_paths = []
for band in bands_num:
in_band = str(op.join(bands_dir, band_prefix) + '{:02d}'.format(band) + '.jp2')
out_band = op.join(intermediate_bands_dir, op.basename(in_band)[0:-4] + '.tif')

resize_band(in_band, out_band, pixelresX, pixelresY)
intermediate_sizes_paths.append(out_band)
return intermediate_sizes_paths


def create_new_indices(additional_bands, bands_dir, new_indices, out_dir_bands, resolution):
for indice in new_indices:
out_tif = op.join(out_dir_bands, (indice + '.tif'))
create_specific_indices(bands_dir, out_tif, indice_name=indice, resolution=resolution)
additional_bands.append(str(out_tif))


def time_diff_feat(additional_bands, global_parameters, paths_parameters, resolution):
bands_num = [int(band) for band in global_parameters["features"]["time_difference_bands"]]
out_dir_bands = op.join(global_parameters["user_choices"]["main_dir"], 'Intermediate')
for band_num in bands_num:
out_tif = op.join(out_dir_bands, ('time_' + str(band_num) + '.tif'))
create_time_difference_band(global_parameters, paths_parameters, band_num, out_tif, resolution=resolution)
additional_bands.append(str(out_tif))


def use_dtm(additional_bands, global_parameters, location, out_dir_bands, resolution):
use_DTM = str2bool(global_parameters["features"]["DTM"])
if use_DTM:
# Append the DTM model
out_dtm = op.join(out_dir_bands, ('DTM.tif'))
# try to append it. If an error occurs, the DTM probably does not exist
# and we will therefore skip this band
try:
dtm_addition(location, out_dtm, resolution=resolution)
additional_bands.append(str(out_dtm))
except:
print('ERROR : THE DTM DOES NOT EXIST !!!')


def create_texture_feat(additional_bands, band_prefix, bands_dir, out_dir_bands):
band_used_for_contours = 2
in_tif = glob.glob(
op.join(bands_dir, '*{}*{:02}.jp2'.format(band_prefix, band_used_for_contours)))[0]
in_channel = 1
out_tif = op.join(out_dir_bands, 'density_contours.tif')
create_contours_density(in_tif, in_channel, out_tif, radius=3)
additional_bands.append(str(out_tif))
out_tif = op.join(out_dir_bands, 'variation_coeff.tif')
create_variation_coeff(in_tif, in_channel, out_tif, radius=3)
additional_bands.append(str(out_tif))


def create_no_data_tif(global_parameters, paths_parameters, out_tif, dilation_radius=10):
'''
Create the no_data TIF using both the clear and cloudy date.
Expand Down
8 changes: 4 additions & 4 deletions alcd_params/global_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,12 @@ class UserChoices(BaseModel):
"""
user_function: Optional[str] = None
user_module: Optional[str] = None
clear_date: str
current_date: str
location: str
clear_date: Optional[str] = None
current_date: Optional[str] = None
location: Optional[str] = None
main_dir: str
raw_img: str
tile: str
tile: Optional[str] = None

@field_validator("clear_date", "current_date")
def parse_yyyymmdd(cls, value: str, info: ValidationInfo) -> str:
Expand Down
16 changes: 8 additions & 8 deletions alcd_params/paths_parameters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pydantic import BaseModel, DirectoryPath
from typing import Dict
from typing import Dict, Optional


class GlobalChainsPaths(BaseModel):
Expand All @@ -24,12 +24,12 @@ class GlobalChainsPaths(BaseModel):
Path to the resized DTM directory.
"""
L1C: DirectoryPath
maja: str
sen2cor: str
fmask: str
fmask3: str
DTM_input: str
DTM_resized: str
maja: Optional[str] = None
sen2cor: Optional[str] = None
fmask: Optional[str] = None
fmask3: Optional[str] = None
DTM_input: Optional[str] = None
DTM_resized: Optional[str] = None


class DataPaths(BaseModel):
Expand All @@ -44,7 +44,7 @@ class DataPaths(BaseModel):
Path to the PCC data directory.
"""
data_alcd: DirectoryPath
data_pcc: str
data_pcc: Optional[str] = None


class TileLocation(BaseModel):
Expand Down
Loading