# HƯỚNG DẪN SỬ DỤNG HỆ THỐNG MỚI

## Tổng quan

Hệ thống đã được cập nhật để chuẩn hóa việc trích xuất features giữa training và prediction, sử dụng module `feature_extractor.py`.

## Các thành phần mới

### 1. feature_extractor.py
Module chuẩn hóa việc trích xuất features với 3 modes:

- **simple**: 3 features cơ bản
  - NDVI_mean
  - VH_db_mean
  - VV_db_mean
  
- **temporal**: 39+ features time-series
  - NDVI_t1, NDVI_t2, ..., NDVI_tn
  - NDWI_t1, NDWI_t2, ..., NDWI_tn
  - NDBI_t1, NDBI_t2, ..., NDBI_tn
  - VH_db_mean, VV_db_mean, VH_VV_ratio
  
- **extended**: 15 features với statistics
  - NDVI_mean, NDVI_std, NDVI_min, NDVI_max
  - NDWI_mean, NDWI_std, NDWI_min, NDWI_max
  - NDBI_mean, NDBI_std, NDBI_min, NDBI_max
  - VH_db_mean, VV_db_mean, VH_VV_ratio

### 2. train_module.py (Đã cập nhật)
- Thêm tham số `feature_mode` (default='simple')
- Sử dụng FeatureExtractor để extract features
- Lưu `feature_mode` vào metadata của model
- Load đúng bands Sentinel-2 theo feature mode

### 3. api_server.py (Cần cập nhật thủ công)
File này quá lớn để tự động replace. Cần thay thế hàm `run_prediction` bằng version mới trong `run_prediction_new.py`.

## Cách sử dụng

### Training với feature modes khác nhau

#### 1. Simple Mode (Mặc định - Nhanh nhất)
```python
from train_module import train_model

result = train_model(
    bbox=[105.6, 9.3, 106.2, 9.8],
    time_range='2023-03-01/2023-05-31',
    max_scenes=12,
    feature_mode='simple',  # 3 features
    model_type='xgboost',
    use_cache=True
)
```

#### 2. Temporal Mode (Cho model_odc.joblib)
```python
result = train_model(
    bbox=[105.6, 9.3, 106.2, 9.8],
    time_range='2023-03-01/2023-05-31',
    max_scenes=12,
    feature_mode='temporal',  # 39+ features
    model_type='random_forest',
    use_cache=True
)
```

#### 3. Extended Mode (Cân bằng speed/accuracy)
```python
result = train_model(
    bbox=[105.6, 9.3, 106.2, 9.8],
    time_range='2023-03-01/2023-05-31',
    max_scenes=12,
    feature_mode='extended',  # 15 features
    model_type='xgboost',
    use_cache=True
)
```

### Prediction
Prediction sẽ tự động detect feature_mode từ model metadata và sử dụng FeatureExtractor tương ứng.

```python
# Prediction sẽ tự động:
# 1. Load model metadata
# 2. Đọc feature_mode từ metadata
# 3. Khởi tạo FeatureExtractor với mode tương ứng
# 4. Extract features giống như training
# 5. Predict
```

## Tạo metadata cho model_odc.joblib

Model hiện tại `model_odc.joblib` được train với 39 features (temporal mode) nhưng chưa có metadata. Tạo metadata:

```bash
python create_odc_metadata.py
```

File này sẽ tạo `model_train/model_odc_info.json` với:
- n_features: 39
- feature_mode: "temporal"
- features: list of 39 feature names

## So sánh các modes

| Feature Mode | N Features | Training Time | Accuracy | Use Case |
|-------------|-----------|---------------|----------|----------|
| simple | 3 | Nhanh nhất | Trung bình | Test nhanh, dataset nhỏ |
| extended | 15 | Trung bình | Tốt | Cân bằng speed/accuracy |
| temporal | 39+ | Chậm nhất | Tốt nhất | Production, dataset lớn |

## Lưu ý quan trọng

### 1. Bands được load
- **simple**: B04, B08, SCL
- **temporal/extended**: B02, B03, B04, B08, B11, SCL

### 2. Cache compatibility
Cache cũ từ trước khi cập nhật sẽ KHÔNG tương thích vì:
- Không có field `feature_mode`
- Features có thể không match

**Giải pháp**: Xóa cache cũ
```bash
rm -rf dataset_cache/*
```

### 3. Model compatibility
- Models cũ (trước cập nhật) sẽ được coi là `feature_mode='simple'` nếu không có metadata
- Models mới sẽ có field `feature_mode` trong metadata

## Workflow đề xuất

### Bước 1: Xóa cache cũ
```bash
rm -rf dataset_cache/*
```

### Bước 2: Tạo metadata cho model_odc.joblib
```bash
python create_odc_metadata.py
```

### Bước 3: Cập nhật api_server.py
Thay thế hàm `run_prediction` (line 834-1295) với nội dung từ `run_prediction_new.py`

### Bước 4: Test training với simple mode
```bash
# Qua web interface hoặc
python test_training_simple.py
```

### Bước 5: Test prediction với model vừa train
```bash
# Qua web interface
# Model sẽ tự động detect feature_mode và extract đúng features
```

### Bước 6: Test với temporal mode (nếu cần accuracy cao)
```bash
python test_training_temporal.py
```

## Troubleshooting

### Lỗi: "feature_mode not found in metadata"
- Model cũ chưa có metadata
- **Giải pháp**: Hệ thống tự động fallback về 'simple' mode

### Lỗi: "Expected X features but got Y"
- Feature extraction không match với training
- **Giải pháp**: Kiểm tra model metadata, đảm bảo feature_mode đúng

### Lỗi: "B11 band not found"
- Sentinel-2 scene thiếu SWIR band
- **Giải pháp**: Hệ thống tự động fallback về B02

## API Changes

### TrainingConfig (Mới)
```python
class TrainingConfig(BaseModel):
    # ... existing fields ...
    feature_mode: str = "simple"  # NEW: 'simple', 'temporal', 'extended'
```

### Model Metadata (Mới)
```json
{
  "feature_mode": "temporal",
  "features": ["NDVI_t1", "NDVI_t2", ...],
  "n_features": 39,
  ...
}
```

## File Structure

```
/home/x79/remote-sensing/
├── feature_extractor.py         # NEW: Core feature extraction module
├── train_module.py              # UPDATED: Uses FeatureExtractor
├── api_server.py                # NEEDS UPDATE: run_prediction function
├── run_prediction_new.py        # NEW: Updated run_prediction code
├── create_odc_metadata.py       # NEW: Generate metadata for model_odc.joblib
├── SYSTEM_UPDATE_GUIDE.md       # This file
└── model_train/
    ├── model_odc.joblib         # Existing 39-feature model
    ├── model_odc_info.json      # TO CREATE: Metadata file
    └── ...
```

## Next Steps

1. ✅ Created feature_extractor.py
2. ✅ Updated train_module.py
3. ⏳ Update api_server.py (manual)
4. ⏳ Create metadata for model_odc.joblib
5. ⏳ Test full workflow

## Contact & Support

Nếu gặp vấn đề, kiểm tra:
1. feature_extractor.py có import được không
2. Model metadata có field `feature_mode` chưa
3. Cache đã được xóa chưa
4. api_server.py đã cập nhật run_prediction chưa
