diff --git a/post_process.py b/post_process.py index b207d7c..75b6414 100644 --- a/post_process.py +++ b/post_process.py @@ -1,4 +1,5 @@ from pathlib import Path +from datetime import datetime import numpy as np import rasterio from rasterio import windows @@ -66,15 +67,46 @@ def process_cropped(season, site_position, site_name): print(f"[PROCESS] Cropping files to fusion valid data bounds: {site_name}, {season}") + # Collect all available DIST_CLOUD files and their dates + dist_cloud_files = {} + for dist_cloud_file in s2_prep.glob("S2A_MSIL2A_*_DIST_CLOUD.tif"): + date_str = dist_cloud_file.stem.split("_")[2] + try: + date_obj = datetime.strptime(date_str, "%Y%m%d") + dist_cloud_files[date_obj] = dist_cloud_file + except ValueError: + continue + + if not dist_cloud_files: + print("[PROCESS] Warning: No DIST_CLOUD files found. Cannot process fusion files.") + return + + dist_cloud_dates = sorted(dist_cloud_files.keys()) + + def find_closest_dist_cloud(target_date_str): + """Find the closest DIST_CLOUD file to the target date.""" + try: + target_date = datetime.strptime(target_date_str, "%Y%m%d") + except ValueError: + return None + + # Find closest date + closest_date = min(dist_cloud_dates, key=lambda d: abs((d - target_date).days)) + return dist_cloud_files[closest_date] + # Determine valid bounds for each fusion file fusion_bounds = {} fusion_rows = {} for fusion_file in fusion_prep.glob("REFL_*.tif"): date_str = fusion_file.stem.split("_")[1] + + # Try exact date first, then find closest dist_cloud = s2_prep / f"S2A_MSIL2A_{date_str}_DIST_CLOUD.tif" if not dist_cloud.exists(): - continue + dist_cloud = find_closest_dist_cloud(date_str) + if dist_cloud is None: + continue with rasterio.open(dist_cloud) as dist_src: dist_bounds = dist_src.bounds diff --git a/run.py b/run.py index b4c7730..9935ffd 100644 --- a/run.py +++ b/run.py @@ -17,7 +17,7 @@ def run_pipeline(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) - download_phenocam(season, site_position, site_name) + # download_phenocam(season, site_position, site_name) # print(f"Generating NDVI for raw data: {site_name}, {season}") # generate_ndvi_raw(season, site_position, site_name) @@ -34,10 +34,10 @@ def run_pipeline(season, site_position, site_name): # run_efast(season, site_position, site_name) # print(f"Post-processing data: {site_name}, {season}") - # process_cropped(season, site_position, site_name) + process_cropped(season, site_position, site_name) # print(f"Generating NDVI for final outputs: {site_name}, {season}") - # generate_ndvi_post_process(season, site_position, site_name) - # create_ndvi_timeseries_post_process(season, site_position, site_name) + generate_ndvi_post_process(season, site_position, site_name) + create_ndvi_timeseries_post_process(season, site_position, site_name) except Exception as e: print(f"Error: {e}") diff --git a/webapp/index.html b/webapp/index.html index 258a1fa..e9c574b 100644 --- a/webapp/index.html +++ b/webapp/index.html @@ -219,17 +219,30 @@ async function findFile(dateStr, source) { const target = new Date(dateStr); - for (let offset = 0; offset < 15; offset++) { - for (const dir of [0, -1, 1]) { - const d = new Date(target); - d.setDate(d.getDate() + offset * dir); - const date = d.toISOString().split("T")[0].replace(/-/g, ""); - // Processed files use DATE_0.geotiff format + // Search outward from target date (0, ±1, ±2, ±3, ...) until we find the closest file + // Check dates in order: exact, then -1, +1, then -2, +2, etc. + // Limit to ±365 days to avoid infinite search + for (let offset = 0; offset <= 365; offset++) { + // Check exact date first (offset=0) + if (offset === 0) { + const date = target.toISOString().split("T")[0].replace(/-/g, ""); const filename = `${date}_0.geotiff`; try { const res = await fetch(`../data/innsbruck/2024/processed/${source}/${filename}`); if (res.ok) return filename; } catch {} + } else { + // Check -offset and +offset days + for (const dir of [-1, 1]) { + const d = new Date(target); + d.setDate(d.getDate() + offset * dir); + const date = d.toISOString().split("T")[0].replace(/-/g, ""); + const filename = `${date}_0.geotiff`; + try { + const res = await fetch(`../data/innsbruck/2024/processed/${source}/${filename}`); + if (res.ok) return filename; + } catch {} + } } } return null; @@ -286,7 +299,7 @@ overlays[source] = L.imageOverlay(canvas.toDataURL(), bounds, { opacity: 0.95 }).addTo(maps[source]); maps[source].fitBounds(bounds); - // Processed files use DATE_0.geotiff format: 20240101_0.geotiff -> extract 20240101 + // Extract date from filename to show the actual date of the file found (closest available date) const dateStr = filename.split("_")[0]; const date = `${dateStr.slice(0,4)}-${dateStr.slice(4,6)}-${dateStr.slice(6,8)}`; document.getElementById(`${source}rgbdate`).textContent = date; @@ -329,7 +342,7 @@ ndviOverlays[source] = L.imageOverlay(canvas.toDataURL(), bounds, { opacity: 0.95 }).addTo(ndvimaps[source]); ndvimaps[source].fitBounds(bounds); - // Processed NDVI files use DATE_0_ndvi.geotiff format: 20240101_0_ndvi.geotiff -> extract 20240101 + // Extract date from filename to show the actual date of the file found (closest available date) const extractedDateStr = filename.split("_")[0]; const date = `${extractedDateStr.slice(0,4)}-${extractedDateStr.slice(4,6)}-${extractedDateStr.slice(6,8)}`; document.getElementById(`${source}ndvidate`).textContent = date; @@ -344,17 +357,30 @@ async function findNDVIFile(dateStr, source) { const target = new Date(dateStr); - for (let offset = 0; offset < 15; offset++) { - for (const dir of [0, -1, 1]) { - const d = new Date(target); - d.setDate(d.getDate() + offset * dir); - const date = d.toISOString().split("T")[0].replace(/-/g, ""); - // Processed NDVI files use DATE_0_ndvi.geotiff format + // Search outward from target date (0, ±1, ±2, ±3, ...) until we find the closest file + // Check dates in order: exact, then -1, +1, then -2, +2, etc. + // Limit to ±365 days to avoid infinite search + for (let offset = 0; offset <= 365; offset++) { + // Check exact date first (offset=0) + if (offset === 0) { + const date = target.toISOString().split("T")[0].replace(/-/g, ""); const filename = `${date}_0_ndvi.geotiff`; try { const res = await fetch(`../data/innsbruck/2024/processed/ndvi/${source}/${filename}`); if (res.ok) return filename; } catch {} + } else { + // Check -offset and +offset days + for (const dir of [-1, 1]) { + const d = new Date(target); + d.setDate(d.getDate() + offset * dir); + const date = d.toISOString().split("T")[0].replace(/-/g, ""); + const filename = `${date}_0_ndvi.geotiff`; + try { + const res = await fetch(`../data/innsbruck/2024/processed/ndvi/${source}/${filename}`); + if (res.ok) return filename; + } catch {} + } } } return null;