Fixed a few smaller things.

This commit is contained in:
Felix Delattre 2026-01-11 19:11:37 +01:00
parent 9981482636
commit 3cb7ba8a26
3 changed files with 77 additions and 19 deletions

View file

@ -1,4 +1,5 @@
from pathlib import Path from pathlib import Path
from datetime import datetime
import numpy as np import numpy as np
import rasterio import rasterio
from rasterio import windows 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}") 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 # Determine valid bounds for each fusion file
fusion_bounds = {} fusion_bounds = {}
fusion_rows = {} fusion_rows = {}
for fusion_file in fusion_prep.glob("REFL_*.tif"): for fusion_file in fusion_prep.glob("REFL_*.tif"):
date_str = fusion_file.stem.split("_")[1] 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" dist_cloud = s2_prep / f"S2A_MSIL2A_{date_str}_DIST_CLOUD.tif"
if not dist_cloud.exists(): 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: with rasterio.open(dist_cloud) as dist_src:
dist_bounds = dist_src.bounds dist_bounds = dist_src.bounds

8
run.py
View file

@ -17,7 +17,7 @@ def run_pipeline(season, site_position, site_name):
# print(f"Downloading data for {site_name}, {season}") # print(f"Downloading data for {site_name}, {season}")
# download_s2(season, site_position, site_name) # download_s2(season, site_position, site_name)
# download_s3(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}") # print(f"Generating NDVI for raw data: {site_name}, {season}")
# generate_ndvi_raw(season, site_position, site_name) # 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) # run_efast(season, site_position, site_name)
# print(f"Post-processing data: {site_name}, {season}") # 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}") # print(f"Generating NDVI for final outputs: {site_name}, {season}")
# generate_ndvi_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) create_ndvi_timeseries_post_process(season, site_position, site_name)
except Exception as e: except Exception as e:
print(f"Error: {e}") print(f"Error: {e}")

View file

@ -219,17 +219,30 @@
async function findFile(dateStr, source) { async function findFile(dateStr, source) {
const target = new Date(dateStr); const target = new Date(dateStr);
for (let offset = 0; offset < 15; offset++) { // Search outward from target date (0, ±1, ±2, ±3, ...) until we find the closest file
for (const dir of [0, -1, 1]) { // Check dates in order: exact, then -1, +1, then -2, +2, etc.
const d = new Date(target); // Limit to ±365 days to avoid infinite search
d.setDate(d.getDate() + offset * dir); for (let offset = 0; offset <= 365; offset++) {
const date = d.toISOString().split("T")[0].replace(/-/g, ""); // Check exact date first (offset=0)
// Processed files use DATE_0.geotiff format if (offset === 0) {
const date = target.toISOString().split("T")[0].replace(/-/g, "");
const filename = `${date}_0.geotiff`; const filename = `${date}_0.geotiff`;
try { try {
const res = await fetch(`../data/innsbruck/2024/processed/${source}/${filename}`); const res = await fetch(`../data/innsbruck/2024/processed/${source}/${filename}`);
if (res.ok) return filename; if (res.ok) return filename;
} catch {} } 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; return null;
@ -286,7 +299,7 @@
overlays[source] = L.imageOverlay(canvas.toDataURL(), bounds, { opacity: 0.95 }).addTo(maps[source]); overlays[source] = L.imageOverlay(canvas.toDataURL(), bounds, { opacity: 0.95 }).addTo(maps[source]);
maps[source].fitBounds(bounds); 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 dateStr = filename.split("_")[0];
const date = `${dateStr.slice(0,4)}-${dateStr.slice(4,6)}-${dateStr.slice(6,8)}`; const date = `${dateStr.slice(0,4)}-${dateStr.slice(4,6)}-${dateStr.slice(6,8)}`;
document.getElementById(`${source}rgbdate`).textContent = date; document.getElementById(`${source}rgbdate`).textContent = date;
@ -329,7 +342,7 @@
ndviOverlays[source] = L.imageOverlay(canvas.toDataURL(), bounds, { opacity: 0.95 }).addTo(ndvimaps[source]); ndviOverlays[source] = L.imageOverlay(canvas.toDataURL(), bounds, { opacity: 0.95 }).addTo(ndvimaps[source]);
ndvimaps[source].fitBounds(bounds); 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 extractedDateStr = filename.split("_")[0];
const date = `${extractedDateStr.slice(0,4)}-${extractedDateStr.slice(4,6)}-${extractedDateStr.slice(6,8)}`; const date = `${extractedDateStr.slice(0,4)}-${extractedDateStr.slice(4,6)}-${extractedDateStr.slice(6,8)}`;
document.getElementById(`${source}ndvidate`).textContent = date; document.getElementById(`${source}ndvidate`).textContent = date;
@ -344,17 +357,30 @@
async function findNDVIFile(dateStr, source) { async function findNDVIFile(dateStr, source) {
const target = new Date(dateStr); const target = new Date(dateStr);
for (let offset = 0; offset < 15; offset++) { // Search outward from target date (0, ±1, ±2, ±3, ...) until we find the closest file
for (const dir of [0, -1, 1]) { // Check dates in order: exact, then -1, +1, then -2, +2, etc.
const d = new Date(target); // Limit to ±365 days to avoid infinite search
d.setDate(d.getDate() + offset * dir); for (let offset = 0; offset <= 365; offset++) {
const date = d.toISOString().split("T")[0].replace(/-/g, ""); // Check exact date first (offset=0)
// Processed NDVI files use DATE_0_ndvi.geotiff format if (offset === 0) {
const date = target.toISOString().split("T")[0].replace(/-/g, "");
const filename = `${date}_0_ndvi.geotiff`; const filename = `${date}_0_ndvi.geotiff`;
try { try {
const res = await fetch(`../data/innsbruck/2024/processed/ndvi/${source}/${filename}`); const res = await fetch(`../data/innsbruck/2024/processed/ndvi/${source}/${filename}`);
if (res.ok) return filename; if (res.ok) return filename;
} catch {} } 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; return null;