diff --git a/efast.py b/call_efast.py similarity index 89% rename from efast.py rename to call_efast.py index 9308111..a9aec22 100644 --- a/efast.py +++ b/call_efast.py @@ -9,14 +9,17 @@ from rasterio.warp import Resampling from rasterio.vrt import WarpedVRT from rasterio import shutil as rio_shutil -try: - import efast - from efast.s2_processing import distance_to_clouds - from efast.s3_processing import reproject_and_crop_s3 -except ImportError: - raise ImportError( - "efast package not found. Install with: pip install git+https://github.com/DHI-GRAS/efast.git" - ) +def _import_efast(): + """Lazy import of efast to avoid import errors when not using efast functions.""" + try: + import efast + from efast.s2_processing import distance_to_clouds + from efast.s3_processing import reproject_and_crop_s3 + return efast, distance_to_clouds, reproject_and_crop_s3 + except ImportError: + raise ImportError( + "efast package not found. Install with: pip install git+https://github.com/DHI-GRAS/efast.git" + ) RESOLUTION_RATIO = 21 @@ -46,8 +49,8 @@ def _reproject_raster_to_target(src_path, dst_path, target_bounds, target_crs, w } with WarpedVRT(src, **vrt_options) as vrt: profile = vrt.profile.copy() - profile.update({"dtype": "float32", "nodata": 0}) - rio_shutil.copy(vrt, dst_path, driver="GTiff", **profile) + profile.update({"dtype": "float32", "nodata": 0, "driver": "GTiff"}) + rio_shutil.copy(vrt, dst_path, **profile) def prepare_s2(season, site_position, site_name, date_range=None): @@ -88,6 +91,7 @@ def prepare_s2(season, site_position, site_name, date_range=None): _reproject_raster_to_target(temp_normalized, refl_dst, target_bounds, target_crs, s2_width, s2_height) temp_normalized.unlink() + _, distance_to_clouds, _ = _import_efast() distance_to_clouds(s2_output_dir, ratio=RESOLUTION_RATIO) @@ -128,6 +132,7 @@ def prepare_s3(season, site_position, site_name, date_range=None): with rasterio.open(composite_path, "w", **profile) as dst: dst.write(composite) + _, _, reproject_and_crop_s3 = _import_efast() reproject_and_crop_s3(temp_composite_dir, s2_prepared_dir, s3_preprocessed_dir) shutil.rmtree(temp_composite_dir) diff --git a/ndvi.py b/ndvi.py index 4a67c8e..84fd348 100644 --- a/ndvi.py +++ b/ndvi.py @@ -94,6 +94,16 @@ def _process_ndvi_files( return for geotiff_file in geotiff_files: + # Check if file has enough bands (need at least 4 for RED and NIR) + try: + with rasterio.open(geotiff_file) as src: + if src.count < 4: + print(f"[NDVI-{source_name}] Skipping {geotiff_file.name} (only {src.count} band(s), need 4+)") + continue + except Exception as e: + print(f"[NDVI-{source_name}] Skipping {geotiff_file.name} (error reading: {e})") + continue + output_file = output_dir / ( output_namer(geotiff_file) if output_namer else geotiff_file.name ) diff --git a/run.py b/run.py index 073a0de..929c072 100644 --- a/run.py +++ b/run.py @@ -1,4 +1,4 @@ -from efast import run_efast, prepare_s2, prepare_s3 +from call_efast import run_efast, prepare_s2, prepare_s3 from ndvi import ( generate_ndvi_raw, create_ndvi_timeseries_raw, @@ -12,8 +12,8 @@ from clouds import detect_clouds def run_pipeline(season, site_position, site_name): try: - print(f"Downloading data for {site_name}, {season}") - download_s2(season, site_position, site_name) + # print(f"Downloading data for {site_name}, {season}") + # download_s2(season, site_position, site_name) # download_s3(season, site_position, site_name) # print(f"Generating NDVI for raw data: {site_name}, {season}") @@ -23,7 +23,7 @@ def run_pipeline(season, site_position, site_name): # print(f"Detecting clouds for {site_name}, {season}") # detect_clouds(season, site_name) - # print(f"Preparing data for EFAST fusion for {site_name}, {season}") + print(f"Preparing data for EFAST fusion for {site_name}, {season}") # prepare_s2(season, site_position, site_name) # prepare_s3(season, site_position, site_name) @@ -31,8 +31,8 @@ def run_pipeline(season, site_position, site_name): # run_efast(season, site_position, site_name) # print(f"Generating NDVI for prepared outputs: {site_name}, {season}") - # generate_ndvi_prepared(season, site_position, site_name) - # create_ndvi_timeseries_prepared(season, site_position, site_name) + generate_ndvi_prepared(season, site_position, site_name) + create_ndvi_timeseries_prepared(season, site_position, site_name) except Exception as e: print(f"Error: {e}")