# HW_EC_10 — Ghi chú để tiếp tục phiên

**Cập nhật:** 2026-09-05 (chiều). NHIỆM VỤ CHÍNH ĐÃ XONG HẾT. Không còn job SLURM /
watcher nào của dự án đang chạy (proc `status_watch.sh` PID 10905 là của dự án KHÁC
`HW_CFS_raw`, KHÔNG đụng vào).

## ✅ BẢN TIN 29/08/2026 trên EC_0.25_SD (A37 — HOÀN TẤT 15:27)
Dựng hệ dự báo nghiệp vụ init 29/08/2026 (giống URL ../HW) trên EC_0.25_SD, cùng Ope1b.
Pipeline realtime MỚI (src/sd/): download_ec15_rt.py → grib_to_netcdf → build_ec_all_sd_rt.py
(EC_all lưới 0.25 đầy đủ: 39 biến nội suy + mn2t6 + mx2t6=frozen-BCSD) → operational_forecast
--from-ecall → make_forecast_html. VALIDATE builder trên hindcast 2003-08-03: mọi biến nội
suy corr=1.00000; mx2t6 BCSD corr .99952.
- KẾT QUẢ: SD ≈ org cho init 29/8 (W1 429 vs 437 ô, đồng thuận 91.9%; W3-W6 98-100%).
  Phủ rộng W4-W6 là đặc tính init cuối tháng 8 (khớp bản tin ../HW). 21 bảng contingency
  (3 điểm×7 vùng) cũng SD≈org từng điểm. Ope1b = hiện thực EXP3 (cổng p=M/N).
- SẢN PHẨM (đã publish qua symlink public_html/For_Me/claude/HW_EC_10 → working dir):
  + ehd_forecast_ope1b_sd.html  — bản tin đầy đủ EC_0.25_SD (bản đồ W1-W6, trường xác suất)
  + ehd_forecast_sd_vs_org.html — so sánh 29/8 org-vs-SD + 21 bảng contingency
  URL: hpc.meteo.edu.vn/~tanpv/For_Me/claude/HW_EC_10/ehd_forecast_ope1b_sd.html

## ✅ KẾT QUẢ CUỐI CÙNG — TÁI TẠO Ope1b TRÊN EC_0.25_SD (A34/A35 — HOÀN TẤT 12:35)
So EHDE của **EC_0.25_SD (downscale từ 1.5° THẬT)** vs **EC_0.25 gốc (../HW ope1b)**,
cùng hệ Ope1b, cùng 416 init valid, cùng code chấm điểm. Kết quả `ehd_sd_vs_native.html`:
- **SD ~ TRÙNG KHÍT native mọi tuần.** W1 CSI 0.553 vs 0.562 (Δ −0.009); |Δ CSI|≤0.010 W1-W6.
- **KẾT LUẬN NGHIỆP VỤ: KHÔNG cần tải/lưu bộ 0.25° gốc — tải 1.5° + AI-downscale là ĐỦ.**
  Nhất quán A10 (0.25° gốc chỉ 5.3% phương sai <1.5°). W1 hệ SD đạt 4.5/5 chỉ tiêu
  (POD .643, POFD đạt, FBI .804, CSI .553; chỉ FAR .201 sát ngưỡng <0.2), y hệt native.
- **ĐÍNH CHÍNH nhận định cũ:** "1.5° THẬT không đạt mục tiêu" (A31, CSI 0.244) chỉ đúng
  cho pipeline ehd_full THÔ. Hệ Ope1b ĐẦY ĐỦ trên 1.5°-downscale đạt W1 CSI 0.553 ≈ native.
  Nút thắt là kiến trúc mô hình + cách đánh giá, KHÔNG phải độ phân giải EC.
- Còn lại (tuỳ chọn): nâng mx2t6 BCSD→AI-LightGBM downscale rồi dựng lại cube (--tx-ds
  pred_lgbm) + train + verify — kỳ vọng cải thiện nhỏ vì SD đã ≈ native.

---
## (LỊCH SỬ) Trạng thái trước khi A34 xong:
TẤT CẢ download (624 grib) + convert + REAL-RUN + EOF/PC ĐÃ XONG.

## TÓM TẮT KẾT QUẢ CUỐI (A31→A33)
- REAL 1.5° (`ehd_full_real.json`): regional_EHDE W1 CSI **0.244** (POD 0.283/FBI 0.441).
- REAL 1.5° + EOF/PC miền rộng (`ehd_full_real_pcs.json`): regional_EHDE W1 CSI **0.246**
  → EOF/PC gh500+t850 CẢI THIỆN KHÔNG ĐÁNG KỂ (+0.002..0.006 CSI dù PC vào top feature).
- **Kết luận chốt:** nút thắt là LƯỢNG THÔNG TIN của 1.5° THẬT, không phải thiếu feature
  quy mô lớn. Proxy W1 CSI 0.48 là trần giả tạo. 1.5° THẬT KHÔNG đạt mục tiêu EHDE.
- Report `ehd_report.html` đã có mục 6 (real+EOF/PC). `developing.txt` đã ghi A33.

## NHIỆM VỤ ĐANG CHẠY (2026-09-05): TÁI TẠO ĐẦY ĐỦ Ope1b TRÊN EC_0.25_SD
Người dùng chốt: dựng Y HỆT hệ ope1b của ../HW, chỉ khác đầu vào = EC_0.25_SD
(Tx downscale). So EHD/EHDE của EC_0.25_SD vs EC_0.25 GỐC (../HW ope1b W1 CSI 0.562).
Mã ở `src/sd/` (copy ../HW, KHÔNG sửa gốc). OUT=`outputs_sd/` -> /work/.../HW_EC_10_sd.
Chi tiết A34 trong developing.txt.
- Cube EC_0.25_SD: `outputs_sd/Cube/` (2080,46,40,541). mx2t6=pred_bcsd (Tx downscale
  THẬT), 39 biến raw+derived nội suy 1.5->0.25 (fill_coarse cho soil trước bilinear),
  mn2t6 từ txtm. build_cube_sd.py (in-RAM rồi tofile, tránh strided lustre chậm). ✓XONG
- Features: calc_climatology (train-only) + calc_thresholds_sd (mx2t6 từ Cube) +
  build_ai_inputs (đã vá tofile). EOF = COPY eof_H500/T850.npz của ../HW (căn theo init,
  large-scale bất biến độ phân giải -> cô lập hiệu ứng downscale Tx). Base rate obs 0.101. ✓XONG
- TRAINING (job array 1400987_1..6): 5/6 XONG (W1,W3,W4,W5,W6, ~16-21 phút, pack tại
  outputs_sd/operational_ope1b/model_W*.joblib + meta_W*.json). W2 CHẠY RẤT CHẬM trên
  compute-1-2 (tầng-1 57 phút, tầng-2 64 phút; bình thường ~18 phút) — vẫn đang chạy
  lúc ghi (11:20, đã 1h57). Không phải lỗi, chỉ node chậm; sẽ ghi model_W2.joblib khi xong.
- TỰ ĐỘNG (2 watcher setsid, SỐNG QUA LOGOUT):
  + PID 1409: chờ model_W2.joblib + queue trống -> `sbatch submit_sd_verify.slurm`
    (forecast 416 init valid + final_verify -> outputs_sd/final_verify_sd.json).
  + PID 1850: chờ final_verify_sd.json -> chạy src/sd/compare_report.py ->
    ehd_sd_vs_native.html. Log: logs/sd_compare.log (dòng "REPORT DONE" = xong).
- KHI QUAY LẠI (chiều 2026-09-05): kiểm tra `cat logs/sd_compare.log`; nếu có REPORT DONE,
  đọc bảng W1-W6 trong ehd_sd_vs_native.html (so EC_0.25_SD vs ../HW ope1b, mốc W1 CSI 0.562)
  -> KẾT LUẬN tải-0.25-hay-1.5, ghi developing.txt + báo người dùng.
  Nếu verify LỖI: debug operational_forecast/final_verify trong src/sd (PYTHONPATH=src/sd).
  Nếu watcher chết: `ls outputs_sd/operational_ope1b/model_W*.joblib` đủ 6 thì chạy tay
  `sbatch submit_sd_verify.slurm`, xong thì `PYTHONPATH=src/sd python src/sd/compare_report.py`.
- SAU ĐÓ (tùy chọn, chưa làm): nâng mx2t6 từ BCSD lên AI-LightGBM downscale (chạy downscale_ai
  trên COARSE=outputs/real/tx_ec_1.5_real.nc), dựng lại cube (--tx-ds pred_lgbm) + train + verify.

## VIỆC CÒN LẠI (tuỳ chọn, chưa làm)
- Tune LẠI ngưỡng phủ regional cho số liệu THẬT (FBI regional ~0.4, báo rất thiếu; gridpoint
  FBI~1 đã tốt). Có thể nhích CSI regional chút ít nhưng khó vượt trần thông tin.
- B3 CNN downscaling (chưa smoke-test) — chỉ ảnh hưởng khâu downscaling, không phải hướng chính.
- Trình bày/kết luận nghiệp vụ: 1.5° không đủ; cần EC 0.25° hoặc nguồn phân giải cao hơn.

---
## (LỊCH SỬ) Ghi lúc 2026-09-03 ~18:00 — các job khi đó còn chạy nền.

---

## 1. VIỆC ĐANG CHẠY — KIỂM TRA TRƯỚC TIÊN KHI QUAY LẠI

```bash
cd /home/tanpv/Progs/claude/HW_EC_10
squeue -u tanpv -o "%.8i %.10j %.2t %.10M %R"          # job SLURM
pgrep -af "run_all_downloads|convert_loop"              # tiến trình nền
for g in txtm srf_daily srf_24h plev wide_plev wide_olr; do
  printf "%-10s %3d/104\n" $g $(ls data/grib/$g/*.grib 2>/dev/null|wc -l); done
```

| Việc | ID | Trạng thái (cập nhật 09-04 16:58) | Log |
|---|---|---|---|
| **REAL-RUN EHD (số liệu THẬT)** | ✅ XONG (1400966+1400967) | Kết quả `outputs/downscale/ehd_full_real.json`. **Regional W1: POD 0.283 / FAR 0.359 / FBI 0.441 / CSI 0.244** — KÉM HẲN proxy (W1 CSI 0.48). Chi tiết + diễn giải A31. Report `ehd_report.html` đã có mục 5 (số liệu THẬT). | A31 |
| Download EC 1.5° (còn wide_plev/olr) | PID 4281, `nohup` | txtm/srf_daily/srf_24h/**plev 104/104 XONG**; wide_plev ~9/104, wide_olr 1/104. wide_* CHỈ cho EOF/PC (thử nghiệm sau), KHÔNG chặn real-run | `logs/full_download.log` |
| Chuyển đổi GRIB→NetCDF (vòng lặp) | PID 6271, `nohup` | bám sát, 0 lỗi, 8480+ file .nc | `logs/convert_loop.log` |
| **WATCHER EOF/PC (hướng a)** | PID ~31706, `nohup` | Chờ wide_plev+wide_olr đủ 2080 nc → tự `build_wide_pcs.py` → `launch_ehd_full` với `--pcs`. Ghi `ehd_full_real_pcs.json`. Còn vài giờ (wide_olr tải sau wide_plev). | `logs/pcs_pipeline.log` |

**REAL-RUN đã tự chạy qua `src/run_real_pipeline.sh` (A30):** build_ec_tx (txtm thật) → BCSD thật (ALL RMSE 2.99 = proxy) → build_ec15_real → launch_ehd_full với `--pred` VÀ `--txds` đều THẬT (đã thêm arg `--txds` vào ehd_full.py để không trộn proxy). Script idempotent, chạy lại được.

**Nếu nohup chết mà download chưa xong:** `cd` vào dự án rồi `nohup ./src/run_all_downloads.sh > logs/full_download.log 2>&1 &` và `nohup ./src/convert_loop.sh > logs/convert_loop.log 2>&1 &` (cả hai tự resume, bỏ qua file đã có).

**Định hướng đã chốt (A25):** downscaling (QM/BCSD/AI) chỉ là TIỀN XỬ LÝ để xác nhận 1.5° dùng được (so với EC 0.25° sau), KHÔNG thay thế ML/DL dự báo EHD/EHDE. Sau downscaling → xây EHD/EHDE bằng AI như session `../HW` (hw_ec_25).

**Chuẩn làm việc mới (A26/A28):**
- Mọi model EHD/EHDE phải xuất `feature_gain`; `make_report.py` đã render feature importance cho mọi model. Ghi đủ chi tiết cho Technical Report.
- **Chạy nặng = ĐA NODE.** `ehd_full.py` đã fold-parallel: `bash src/launch_ehd_full.sh --out <json> --part-dir <dir>` nộp array 5 fold (1 node/fold) + reduce (dependency). Dùng cho lần chạy số liệu 1.5° THẬT.
- **`build_ec15_real.py`** dựng predictor từ `data/nc/` (drop-in thay proxy), đã smoke-test OK; chạy full khi plev tải xong: `/home/tanpv/.conda/envs/ehd/bin/python -u src/build_ec15_real.py --jobs 10`.
- **`ehd_full.py` có `--pred`** (mặc định proxy). Chạy trên số liệu THẬT khi có `outputs/real/ec15_predictors.nc`:
  `bash src/launch_ehd_full.sh --pred outputs/real/ec15_predictors.nc --out outputs/downscale/ehd_full_real.json --part-dir outputs/downscale/fold_parts_real`

**Kết quả proxy đã chốt (A29):** re-tune (dò ngưỡng EHDE vùng + FBI≤1.0) đã trị FBI bung. regional_EHDE: W1 POD 0.63/POFD 0.06/FAR 0.32/FBI 0.93/CSI 0.48 (đạt 3/5); W2-W6 kỹ năng thấp, model báo thiếu có kỷ luật (FBI~1, POFD<0.13). Đa-node trùng khớp single-node → pipeline `launch_ehd_full.sh` tin dùng được.

**Tiến trình `nohup` và job SLURM đều sống qua việc thoát phiên.** Monitor thì không — phải tự dựng lại.

- Download: ~34 file/giờ ⇒ còn ~17 giờ nữa mới đủ 624 file. Tự resume (bỏ qua file đã có), 0 lỗi tính đến lúc ghi.
- `ds_ai` chậm bất thường: 1 lần `fit` LightGBM (4 tr hàng × 21 đặc trưng, 700 cây × 127 lá) mất >45 phút. Nếu quay lại thấy vẫn lê thê, **giảm `n_estimators` xuống 300 và `num_leaves` xuống 63** rồi chạy lại. Kết quả này chỉ ảnh hưởng khâu downscaling, KHÔNG chặn hướng chính.
- Nếu vòng lặp convert đã thoát mà download còn chạy, khởi động lại: `nohup ./src/convert_loop.sh > logs/convert_loop.log 2>&1 &`

---

## 2. VIỆC TIẾP THEO, THEO THỨ TỰ ƯU TIÊN

1. **Đọc kết quả `ehd_full`** (`logs/slurm_full_1400935.log`, `outputs/downscale/ehd_full.json`).
   Đây là câu hỏi trung tâm: 1.5° có đủ thông tin đạt POD>0.6 / FAR<0.2 / CSI>0.4 không?
   Xem cả `feature_gain` để biết biến nào thực sự có ích.
2. **Sinh báo cáo:** `python src/make_report.py` → `ehd_report.html`. Tự thích ứng với các JSON đã có.
3. **Chấm điểm sự kiện cho LightGBM downscaling** khi `ds_ai` xong:
   `python src/evaluate_ehd.py --pred outputs/downscale/pred/pred_lgbm.npy --out outputs/downscale/ehd_lgbm.json`
4. **Chạy B3 (CNN)** nếu muốn thử tiếp downscaling — code đã viết sẵn, chưa chạy lần nào:
   `sbatch --array=0-4 ... src/downscale_cnn.py --fold $SLURM_ARRAY_TASK_ID`
   (mỗi fold một job vì torch chỉ có bản CPU; **chưa được kiểm thử**, cần smoke test trước).
5. **Khi download xong:** chạy lại toàn bộ trên số liệu 1.5° THẬT thay cho proxy.
   Cần viết bộ dựng `ec15_predictors.nc` từ `data/nc/` (tương tự `build_ec_proxy_all.py`
   nhưng đọc từ NetCDF đã tải thay vì kho 0.25°). Cấu trúc file đã kiểm chứng là khớp.

---

## 3. NHỮNG KẾT LUẬN ĐÃ CHỐT — ĐỪNG LÀM LẠI

Chi tiết đầy đủ trong `developing.txt` (mục A1–A22). Tóm tắt:

- **Đặc tả request ECDS** (A11): `level_type="pressure"`, khoá mực là `level_value`, giá trị `"500_hpa"`, `data_format="grib"`. `mx2t6/mn2t6` dùng leadtime dạng ĐIỂM (6..1104), không phải khoảng.
- **Gộp nhiều ngày mv vào 1 request KHÔNG lợi** (A12) — đã đo, đừng thử lại.
- **Baseline downscaling** (A16): bilinear 3.29 / QM 3.07 / **BCSD 2.99** RMSE (°C). BCSD là mốc phải vượt.
- **Chuỗi 3 phát hiện quan trọng nhất** (A18→A19→A21):
  1. Downscale Tx rồi cắt ngưỡng → CSI 0.143 (điểm lưới) / 0.203 (vùng). Xa mục tiêu.
  2. Đổi sang mô hình phân loại với CÙNG thông tin → CSI 0.132–0.135. **Không hơn.**
  3. Với riêng Tx, **không ngưỡng nào** thoả POD≥0.6 và FAR≤0.2. Đường ROC không đi qua vùng yêu cầu.
  ⇒ Nút thắt là **LƯỢNG THÔNG TIN**, không phải cách đặt bài toán hay chỉnh ngưỡng.
- **Chỉ tiêu gốc tự mâu thuẫn**: `FAR = 1 − POD/FBI` là ĐẲNG THỨC. Ép FBI~1 thì FAR<0.2 đòi POD>0.8.
  Người dùng đã quyết: giữ POD>0.6 và FAR<0.2, **nới FBI về ~0.75**. Đã ghi vào `CLAUDE.md`.
- **`dz` = orog − orog_coarse** trải −700..+1087 m ⇒ sai số hệ thống −4.5..+7.0 °C mà 1.5° không biểu diễn được. Predictor bắt buộc.
- **Bộ EC 0.25° cũ KHÔNG phải nội suy của 1.5°** (A10): mang 5.3% phương sai ở quy mô <1.5°, RMS 0.99 K. Dùng làm mốc so sánh thứ hai cho downscaling.

## 4. BẪY KỸ THUẬT ĐÃ VẤP — TRÁNH LẶP

- Chained indexing `arr[:,:,a:b][..., idx] = True` gán vào bản sao tạm → mọi metric ra NaN.
- `NaN * 0 = NaN` trong matmul: một ô thô rỗng đầu độc toàn bộ nội suy. Đã có `fill_coarse_nan()`.
- BCSD sai 2 chỗ (A15): trung bình quan trắc về ô thô phải CHỈ trên điểm đất; dị thường phải lấy so với khí hậu QUAN TRẮC thô, không phải khí hậu dự báo chưa hiệu chỉnh.
- Mảng `prob` dùng chung cho inner-val và test → fold sau ghi đè fold trước. Phải tách 2 mảng.
- `tp/cp` sau khử tích luỹ có 0.35% giá trị âm (biên độ ~1.1 mm, KHÔNG phải nhiễu làm tròn) → đã cắt về 0 trong pipeline.
- Đừng nối lệnh chạy dài vào `| tail` (bị đệm, mất sạch output khi timeout). Dùng SLURM + `python -u`.
- `pkill -f "<tên script>"` khớp luôn chính lệnh shell đang chạy → tự giết mình.

## 5. LƯU Ý VỀ TÍNH TRUNG THỰC CỦA SO SÁNH

Mọi số hiện có đều dựng trên **proxy 1.5°** (trung bình kho EC 0.25° lên lưới 1.5° thật), **toàn mùa, toàn hạn**. Phiên HW trước đạt POD 0.628 / FAR 0.395 / CSI 0.446 nhưng với mô hình phân loại, **chỉ mùa nóng**, phủ 20%, ngưỡng riêng theo (vùng,tuần). **KHÔNG so sánh trực tiếp hai bộ số này.**
