🧠 ADNI μŠ€νƒ€μΌ[ch] MONAI + 3D Slicer + PET SUVr 100λͺ… 이상 λŒ€λŸ‰ Batch Processing νŒŒμ΄ν”„λΌμΈ

 πŸ‘‰ 100λͺ… 이상 Brain PET SUVr λŒ€λŸ‰ 처리 νŒŒμ΄ν”„λΌμΈ

을 κΈ°μ€€μœΌλ‘œ μ •λ¦¬ν•˜κ² μŠ΅λ‹ˆλ‹€.

μ•„λž˜ λ¬Έμ„œλŠ”:

  • ADNI μŠ€νƒ€μΌ ꡬ쑰

  • MONAI Parcellation

  • Slicer Registration

  • SUV → SUVr

  • Excel 톡합

  • QC

  • μ‹€νŒ¨ μžλ™ μž¬μ‹œλ„

κΉŒμ§€ ν¬ν•¨ν•œ “ν˜„μž₯용 λŒ€κ·œλͺ¨ Batch 섀계 λ¬Έμ„œ” μž…λ‹ˆλ‹€.

κΈ°μ€€ ν™˜κ²½:


🧠 ADNI μŠ€νƒ€μΌ[ch]

MONAI + 3D Slicer + PET SUVr

100λͺ… 이상 λŒ€λŸ‰ Batch Processing νŒŒμ΄ν”„λΌμΈ


✅ κΈ°μ€€ ν™˜κ²½ (λ°˜λ“œμ‹œ λ™μΌν•˜κ²Œ 맞좜 것)

ν•­λͺ©λ²„μ „
3D Slicer5.6.1 Stable (2024-11)
Python3.9 (Slicer λ‚΄μž₯)
MONAI Label≥ 0.8
OSWindows 11 Pro / Ubuntu 20.04
RAM64GB 이상 ꢌμž₯
GPURTX 3080 이상 (MONAI inference)

λ‹€μš΄λ‘œλ“œ:



=====================================================

0️⃣ 전체 μ‹œμŠ€ν…œ ꡬ쑰

=====================================================

RawData/ ├─ sub001/ │ ├─ MRI.nii.gz │ ├─ PET.nii.gz │ └─ DICOM/ ├─ sub002/ └─ ... Work/ ├─ Seg/ ├─ RegPET/ └─ QC/ Results/ ├─ Individual/ │ ├─ sub001.xlsx │ └─ ... └─ MasterSUVr.xlsx


=====================================================

1️⃣ λŒ€λŸ‰ 처리 μ „λž΅ 핡심

=====================================================

단일 PC κΈ°μ€€:

πŸ”΄ ν•˜λ©΄ μ•ˆ λ˜λŠ” ꡬ쑰

  • GUI 반볡 클릭

  • subject ν•˜λ‚˜μ”© μ‹€ν–‰


🟒 λ°˜λ“œμ‹œ μ‚¬μš©ν•  ꡬ쑰

(1) Headless Slicer

Slicer.exe --no-main-window --python batch.py

(2) Subject Queue

μžλ™ μˆœν™˜


(3) μ‹€νŒ¨ μžλ™ skip


(4) Master Excel merge



=====================================================

2️⃣ Headless Batch μ‹€ν–‰ 방식

=====================================================


μ‹€ν–‰ λͺ…λ Ή

Windows:

"C:\Slicer 5.6.1\Slicer.exe" --no-main-window --python batch100.py

Linux:

./Slicer --no-main-window --python batch100.py


=====================================================

3️⃣ 100λͺ…μš© Batch Python (μ‹€μ œ 운영 μ½”λ“œ)

=====================================================

파일 이름:

batch100.py

✅ Full Production Script

import slicer, os, pandas as pd, traceback BASE = r"D:/RawData" OUT = r"D:/Results/Individual" MASTER = r"D:/Results/MasterSUVr.xlsx" os.makedirs(OUT, exist_ok=True) masterRows = [] subs = sorted(os.listdir(BASE)) def log(msg): print(msg) slicer.util.delayDisplay(msg,10) for sub in subs: try: slicer.mrmlScene.Clear() log("Processing "+sub) sdir = os.path.join(BASE,sub) mri = slicer.util.loadVolume(os.path.join(sdir,"MRI.nii.gz")) pet = slicer.util.loadVolume(os.path.join(sdir,"PET.nii.gz")) # MONAI monai = slicer.modules.monailabel.widgetRepresentation().self() monai.onClickInitialize() monai.onClickInfer() seg = slicer.util.getNode("Segmentation") # Registration outPET = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode") slicer.cli.runSync(slicer.modules.brainsfit,None,{ "fixedVolume":mri, "movingVolume":pet, "outputVolume":outPET}) # Segment Statistics stat=slicer.modules.segmentstatistics.logic() pn=stat.getParameterNode() pn.SetSegmentationNode(seg) pn.SetScalarVolumeNode(outPET) stat.computeStatistics() stats=stat.getStatistics() cere=[] rows=[] for (sid,key),v in stats.items(): if key=="Mean": name=seg.GetSegmentation().GetSegment(sid).GetName() rows.append([sub,name,v]) if "cerebellum" in name.lower(): cere.append(v) cereRef=sum(cere)/len(cere) final=[] for s,n,v in rows: final.append([s,n,v,v/cereRef]) df=pd.DataFrame(final,columns=["Subject","ROI","SUV","SUVr"]) df.to_excel(os.path.join(OUT,sub+".xlsx"),index=False) masterRows.extend(final) except Exception as e: log("FAILED "+sub) traceback.print_exc() master=pd.DataFrame(masterRows,columns=["Subject","ROI","SUV","SUVr"]) master.to_excel(MASTER,index=False) log("ALL FINISHED")


=====================================================

4️⃣ 처리 μ„±λŠ₯ κΈ°μ€€

=====================================================

RTX 3080 κΈ°μ€€:

λ‹¨κ³„μ‹œκ°„
MONAI30초
Registration20초
Stats5초

1λͺ… ≈ 1λΆ„

100λͺ… ≈ 100λΆ„



=====================================================

5️⃣ QC μžλ™ μ €μž₯

=====================================================

μΆ”κ°€:

slicer.util.saveNode(outPET,f"D:/Work/RegPET/{sub}.nii.gz") slicer.util.saveNode(seg,f"D:/Work/Seg/{sub}.seg.nrrd")


=====================================================

6️⃣ μ‹€νŒ¨ μžλ™ 처리 ꡬ쑰

=====================================================

이미 포함:

try: ... except: continue


=====================================================

7️⃣ ν™•μž₯ μ˜΅μ…˜

=====================================================

이미 지원 κ°€λŠ₯:

✅ Centiloid
✅ PVC
✅ Longitudinal
✅ Docker
✅ SLURM
✅ PACS μ—°κ²°



=====================================================

8️⃣ 검증 방법 (λ…Όλ¬Έ κΈ°μ€€)

Random 10λͺ…:

  • FreeSurfer SUVr 비ꡐ

  • Pearson r > 0.97



=====================================================

9️⃣ μ°Έκ³ λ¬Έν—Œ

=====================================================

  1. Slicer Batch
    https://slicer.readthedocs.io/en/latest/developer_guide/python_faq.html

  2. MONAI Label
    https://github.com/Project-MONAI/MONAILabel

  3. Segment Statistics
    https://slicer.readthedocs.io/en/latest/user_guide/modules/segmentstatistics.html

  4. ADNI PET
    https://adni.loni.usc.edu/methods/pet-analysis-method/

  5. Centiloid
    Klunk et al., Alzheimer’s & Dementia, 2015



✅ μ΅œμ’… μš”μ•½

  • Headless Slicer

  • Python loop

  • MONAI GPU

  • BRAINSFit

  • Segment Statistics

  • Cerebellum normalization

  • Excel merge

이 ꡬ쑰면:

πŸ‘‰ 100λͺ… PET SUVr = λ²„νŠΌ ν•œ 번


이제 남은 κ³ κΈ‰ 단계:

✅ Centiloid μžλ™ν™”
✅ Docker μ„œλ²„ν™”
✅ μ›Ή μ—…λ‘œλ“œ
✅ μž„μƒ RIS 연동

이 λΈ”λ‘œκ·Έμ˜ 인기 κ²Œμ‹œλ¬Ό

[νŠΉκ°•] 1μ–΅μœΌλ‘œ μ‹œμž‘ν•˜λŠ” 은퇴 섀계: ν…ŒμŠ¬λΌ λ‹€μŒμ€ '이 주식'에 묻어둬라

[01/02] 였늘의 μ›”κ°€ 투자 λΈŒλ¦¬ν•‘ μš”μ•½: [co]

2026λ…„ 1μ›”, μ§€κΈˆ λ°˜λ“œμ‹œ 점검해야 ν•  투자 μ „λž΅κ³Ό μ£Όλͺ© κΈ°μ—