SmartCane/python_app/harvest_detection_experiments/tests/test_doy_logic.py
Timon fabbf3214d Enhance harvest detection logic and testing framework
- Updated `detect_mosaic_mode` function to check for grid-size subdirectories in addition to tile-named files.
- Added comprehensive tests for DOY reset logic in `test_doy_logic.py`.
- Implemented feature extraction tests in `test_feature_extraction.py`.
- Created tests for growing window method in `test_growing_window_only.py`.
- Developed a complete model inference test in `test_model_inference.py`.
- Added a debug script for testing two-step refinement logic in `test_script22_debug.py`.
2026-01-15 14:30:54 +01:00

66 lines
2.7 KiB
Python

"""
Test DOY reset logic for harvest detection.
Verify that DOY resets to 1, 2, 3, ... after harvest is detected.
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path.cwd()))
import pandas as pd
import numpy as np
from harvest_date_pred_utils import extract_features, load_model_and_config
import torch
# Load sample data
ci_data = pd.read_csv('../laravel_app/storage/app/angata/Data/extracted_ci/ci_data_for_python/ci_data_for_python.csv')
ci_data['Date'] = pd.to_datetime(ci_data['Date'])
# Get field 779 data
field_779 = ci_data[ci_data['field'] == '779'].reset_index(drop=True)
print(f"Field 779: {len(field_779)} days of data")
print(f"Date range: {field_779['Date'].min().date()} to {field_779['Date'].max().date()}\n")
# Load model config
model, config, scalers = load_model_and_config(Path.cwd())
# Test 1: First season (season_anchor_day = 0)
print("=" * 80)
print("TEST 1: First season (season_anchor_day=0, lookback_start=0)")
print("=" * 80)
window = field_779.iloc[0:20].copy().reset_index(drop=True)
features = extract_features(window, config['features'], ci_column='FitData',
season_anchor_day=0, lookback_start=0)
# Extract DOY_normalized column (index 13 or find it)
feature_names = config['features']
doy_idx = feature_names.index('DOY_normalized') if 'DOY_normalized' in feature_names else -1
if doy_idx >= 0:
doy_values = (features[:, doy_idx] * 450).astype(int) # Denormalize
print(f"Window size: {len(window)} days")
print(f"DOY values: {doy_values[:10]}")
print(f"Expected: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]")
assert list(doy_values[:10]) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "DOY not incrementing correctly!"
print("✓ DOY incrementing correctly for first season\n")
# Test 2: After harvest detected at day 100, next season starts
print("=" * 80)
print("TEST 2: After harvest at day 100, new season starts (season_anchor_day=101, lookback_start=101)")
print("=" * 80)
harvest_day = 100
window = field_779.iloc[harvest_day:harvest_day+20].copy().reset_index(drop=True)
features = extract_features(window, config['features'], ci_column='FitData',
season_anchor_day=harvest_day+1, lookback_start=harvest_day+1)
if doy_idx >= 0:
doy_values = (features[:, doy_idx] * 450).astype(int) # Denormalize
print(f"Window size: {len(window)} days (starting at day {harvest_day})")
print(f"DOY values: {doy_values[:10]}")
print(f"Expected: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (fresh season)")
assert list(doy_values[:10]) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "DOY not reset after harvest!"
print("✓ DOY reset correctly for new season\n")
print("=" * 80)
print("ALL TESTS PASSED! DOY logic is correct.")
print("=" * 80)