CBT_project/AGENTS.md
Xiao Furen 332226f843 Add pixi.toml configuration for project dependencies and tasks
- Created a new pixi.toml file to manage project dependencies and tasks.
- Defined workspace metadata including authors, channels, name, platforms, and version.
- Specified tasks for preprocessing, PSO, DE, and other scripts.
- Listed dependencies for Python and various libraries with specific versions.
- Configured additional PyPI options for PyTorch installation from a custom index.
2026-10-19 20:34:28 +08:00

7.4 KiB
Raw Permalink Blame History

AGENTS.md

本文件提供 AI 編碼代理(Kilo / Claude 等)在 CBT_project 內工作時的指引。

專案概述

CBT(Cortical Bone Trajectory,皮質骨軌跡):在腰椎 CT(L1–L5)上自動規劃椎弓根螺絲(pedicle screw)軌跡。將螺絲建模為圓柱體,以 PSO / DE / Nelder-Mead 最佳化在骨頭 mask 上評分(皮質骨接觸、椎體 VBODY 獎勵、tip 處罰、入口端 0.5mm 豁免),取得最佳位置/角度/尺寸後再映回 native CT 空間。

執行環境

  • Python 環境:pixi(conda env cbt 已棄用)。環境在 .pixi/envs/default/,python 3.14;pixi.toml 定義全部依賴與 tasks。VS Code 已設定 python.defaultInterpreterPath 指向 pixi env。
  • xfr_*.py 的 shebang 為 #!/usr/bin/env python,需先 pixi shell / pixi run(或 VS Code 選到 pixi interpreter)才有對的 python。
  • 重建環境:pixi install(torch 走 extra-index-urls 的 pytorch cu126 index,版本 pin 在 pixi.toml)。
  • 主要依賴(皆 pypi):torch(CUDA,GPU 最佳化)、SimpleITK、scipy、scikit-learn、numpy、nibabel、tinydb、pyswarm、matplotlib。conda 端只有 python。
  • 無測試、無 lint 設定。驗證方式:跑小批量 volume、檢查 logs/ 與結果 CSV、以及螺絲柱 in-label 比例(xfr_cbt_native 的 docstring 有驗收標準)。

資料位置(皆在 repo 之外,勿把大檔 commit 進 repo)

用途 路徑
原始 CT / label(CTSpine1K) /mnt/1220/Public/dataset/Spine/CTSpine1K/{data,label}/(子資料夾:colon(=conlon)、COVID-19、HNSCC-3DCT-RT_neck、liver(=Liver))
標準化輸出(current) /mnt/1248/open2/cyrou/CBT/Seg/Resample/standardized-xfr-3/
最終輸出(cbt.nii.gz、X 光投影) /mnt/1248/open/cyrou/Output/
元資料庫(TinyDB) repo 根目錄 xfr_image_metadata.json(table images,key = volume name)
進度 / 日誌 / 結果 progress.json、logs/、results/(皆已被 gitignore)

xfr_*.py 頂部有 hardcode 的資料路徑(standardized_dir、data_root、label_root、Output_dir);跑別世代資料時改這些常數,不要假設 CLI 可覆蓋。

目錄結構

core/          圓柱生成(torch)、中心線相交、評分、objective、optimizer(PSO/DE/NM)
imaging/       nifti_io、preprocessing、resample、affine、orientation、segmentation、transforms
visualization/ res_bone_figure(四視角螺絲圖)、res_plot_3d、res_cyl_nifti(存 NIfTI)、res_cyl_to_CT(overlay)
config/        constant.py(LABEL_MAP、螺絲尺寸、OVERLAP_THRESH、DEFAULT_SPACING)、device.py
utils/         helpers.py(retry_robust、unique filepath、save_with_unique_name)
xfr_*.py       現世代管線入口腳本(見下)
run_*.py       舊世代多 GPU 批次 / benchmark 腳本(base_dir 不同,較少使用)
references/    文獻 PDF(唯讀參考,勿改)
experiment.ipynb  實驗 notebook

管線流程與入口腳本

入口腳本都有對應 pixi task:pixi run <task> -- <args>(task 清單在 pixi.toml [tasks]:preprocess、pso、de、check-spinous、rerender-spinous、cbt-native、record-planes、plot-level)。以下直接列腳本名,加 ./ 前缀在 pixi 環境內亦可執行。

  1. 預處理:xfr_preprocess.py [--max-images N] [--output-dir DIR] 裁切各 level、重取樣到 0.5mm、方向正規化(best_symmetry_plane / best_upper_endplate_plane),輸出 <vol>/crop/ 與各 level 的 mask,並把仿射鏈寫進 <vol>/transform.json。 跳過條件:z spacing > 4mm、lumbar label < 2、椎弓根寬度 > 18mm(clip 並標 _clipped)。
  2. 最佳化:xfr_pso.py [volume_id [level]] [--screw-shape cone|cylinder](DE 版:xfr_de.py) 每 level 左/右各跑一支 PSO,輸出螺絲參數與 render_bone_figure 四視角圖、CSV。
  3. 驗證:xfr_check_spinous.py、xfr_rerender_spinous.py(棘突檢查/重繪)。
  4. 映回 native:xfr_cbt_native.py <run_id> [volumes...] [--date D] 用 transform.json 正向鏈把螺絲映回 native CT,輸出 cbt.nii.gz(label 1–10 = L1L…L5R)與 x-ap/x-lat/z-ap/z-lat 投影圖。
  5. 輔助:xfr_record_planes.py(記錄平面入 transform.json)、xfr_inverse_transform.py(單一 mask 逆向映射)、xfr_orig_labels.py(原始 label 對齊)、xfr_reprocess_ap.py(AP 方向修正)、xfr_plot_level.py(單 level 圖)、xfr_migrate_crop.py(舊佈局遷移到 crop/)。

程式慣例(重要)

  • 註解 / docstring 用繁體中文,識別符號用英文。新增碼保持同風格。
  • 座標系:numpy 體積為 (Z, Y, X);螺絲參數 pos = [z, y, x, az°, alt°, d_mm, L_mm](xfr 變體為 [z, x, az°, alt°, d, L],y 由 y_indices surface 推導,見 core/optimizer.py::get_first_nonzero_y)。spacing 為 [sx, sy, sz],預設 0.5 isotropic。
  • Objective API:新碼一律用 core/objective.py 的 OptimizationContext + make_objective_function[_xfr]。禁止依賴 module globals(set_global_context / objective_function 是 legacy 兼容路徑,保留勿擴充)。
  • 螺絲尺寸離散化:snap_to_discrete_values(config.constant.ALLOWED_DIAMETERS/ALLOWED_LENGTHS);xfr 管線用 snap_to_discrete_values_xfr(core/cylinder.py 的 points 允許 (d, L) 組合表)。xfr 還做 0.9/0.1 混合(diameter_loss = .9*discrete + .1*raw)。
  • transform.json 是 native 映射的單一事實來源(imaging.transforms.original_to_source)。fallback 重算路徑僅供舊世代 volume;改映射邏輯時先讀 xfr_cbt_native.py docstring 的驗證紀錄。
  • 元資料庫是 TinyDB:用 xfr_preprocess.py::_upsert_by_name 一類的 upsert 寫入;勿手改 JSON 結構(legacy 遷移邏輯對結構敏感,見 _migrate_legacy_metadata)。
  • NFS 瞬時錯誤:輸出樹在 NFS 上,os.makedirs/寫檔可能短暫 ENOENT/EEXIST。沿用 utils.helpers.retry_robust 或 core/optimizer.py::_makedirs_retry 的重試模式;勿裸 os.makedirs 建輸出目錄。
  • 日誌:腳本寫 logs/xfr_<script>_<timestamp>.log;logger 名稱與腳本一致。
  • 不覆蓋輸出:存檔用 utils.helpers.get_unique_filepath / save_with_unique_name(自動 _1, _2 後綴)。
  • 檔案命名含螺絲參數時,長度進檔名不帶小數(35.0→35)、直徑保留一位小數(utils.helpers._fmt_length)。

多 GPU / 批次

run_all_cases.py --gpu N --total_gpus M:病人依 index % total_gpus 分配;run_benchmark.py / run_de.py / run_pso.py 為 benchmark 腳本,結果 CSV 在 optimization_benchmark_results_*.csv。舊腳本的 base_dir 指向 /home/cyrou/...(可能已遷移),跑前確認路徑。

修改注意事項

  • references/ 唯讀。
  • xfr_image_metadata.json、progress.json、logs/、results/、.kilo/ 已 gitignore,勿 commit。
  • core/scoring.py、imaging/orientation.py 有 xfr 版本(cl_score_torch_xfr、segment_spinous_process 等)與原版並存;改評分邏輯時確認呼叫方用哪個版本(objective 目前用 _xfr)。
  • 改 LABEL_MAP 或 level 集合時,同步檢查 xfr_cbt_native.py 的 label 值定義(L1L=1 … L5R=10)。
  • GPU 不可用時多數 torch 路徑會 fallback CPU,但速度極慢;跑完整最佳化前確認 CUDA 可用。