從 BAM 檔的 MM/ML 標籤,到一張 read × CpG 的可分析矩陣,中間經過一連串解析與篩選。這頁把每一步拆開,每個門檻都標出源碼行號,並澄清「篩選」在 ISM 裡其實是兩件完全不同的事。
ISM 把每條 read 上 ONT basecaller 標記的每個 CpG 甲基化機率抽出來,對齊到參考基因組座標,組成一張「哪條 read 在哪個 CpG 是否甲基化」的矩陣。讀=解析 MM/ML 標籤+CIGAR 對位;篩=沿路丟掉不可信/不合格的 read、位點、與模糊訊號。
▸ 給教授一句話:甲基「讀取」是 BAM 標籤解析(5mC-only、CpG-context、機率=ML/255);甲基「篩選」要分兩層 — 處理層(QC+覆蓋+二值化灰帶丟棄,決定什麼進矩陣)與應用層(已測的甲基 variant-filter formulation 為 TESTED NEGATIVE;新假說仍可經 pre-decision audit 重開)。兩者常被混為一談。
完整定義在 名詞地基;這裡放本頁會反覆用到的 7 個,點開看一句話定義。
C+m?,2,1,0=跳 2 個 C → 標、再跳 1 個 → 標、再跳 0 個 → 標。C+m? 代表 5mC,C+h? 代表 5hmC。C+m?)與 5hmC(C+h?)。ISM 只取 5mC 當訊號;5hmC 的機率值只用來「對齊 ML 索引」,不進矩陣。ref[i]=='C' && ref[i+1]=='G',不在 CpG 脈絡的修飾呼叫直接丟棄。MM/ML 標籤 — ISM 讀的就是它的輸出,不自己重判。M=比對(讀與參考都前進)、I=插入(讀有、參考無)、D=缺失(參考有、讀無)、S=soft-clip、N=skip。ISM 用它把「read 上第幾個鹼基」換算成「基因組第幾號座標」。somatic=腫瘤後天才出現(只在腫瘤細胞);germline=生殖系遺傳(全身都有)。ISM 以 somatic SNV 當錨點(要驗的目標)、germline 單倍型(HP)當骨幹(可信的分群依據)。+0.005 的 ribbon;即使 ΔF1>0,只要低於 ribbon 就視為實質無改善。甲基 filter 的 ΔF1=+0.00242 正落在 ribbon 之下。核心檔案 MethylationParser::parse_read()。輸入一條 BAM read,輸出它在每個 CpG 的甲基化機率。下圖是五個步驟。
M=比對、I=插入、D=缺失、S=soft-clip(完整定義見 §① CIGAR 卡)。MM: C+m?,2,1,0、ML: [230, 51, 200]:
| 項目 | 內容 | 來源 / 行號 |
|---|---|---|
| 輸入 | 一條 bam1_t(含 MM/ML/CIGAR/HP)+該區參考序列 + ref 起點座標 | parse_read() MethylationParser.cpp:15 |
| 目標修飾 | 只取 C+m?(5mC);C+h?(5hmC)跳過但計入 ML 偏移 | MethylationParser.cpp:60, 71‑82 |
| 機率 | prob = ML[ml_offset+i] / 255.0,型別 float ∈ [0,1] | MethylationParser.cpp:140, 180 |
| 座標對位 | CIGAR 走訪建 seq→ref 映射;插入(I)/soft-clip(S) 標 −1(無參考座標) | build_seq_to_ref_map :232‑281 |
| CpG 驗證 | forward 找 C 且 ref 下一位是 G;reverse 反向找 G 且前一位是 C | :176‑178(fwd), :138‑139(rev) |
| 輸出 | vector<MethylCall>,每個 = (ref_pos 1‑based, probability) | MethylationParser.hpp:14‑22 |
MM 標籤是按原始 read 的 5'→3' 順序列出 delta 的。但比對到負股(reverse strand)的 read,BAM 裡存的 SEQ 是反向互補(3'→5' 的原 read)。所以要從 seq_len−1 往 0 掃,才能對上 MM 的順序;而且原本的 C 在反向互補後變成 G,故負股要找的目標鹼基是 'G'(CpG 的 G 端)。
原始註解與邏輯:MethylationParser.cpp:104‑157。這是甲基讀取最容易出錯的一段 — 弄反會讓負股所有甲基呼叫錯位。
矩陣先以原始機率存(raw),要算二值距離時再用兩個門檻壓成三態。這一步會悄悄丟掉「模糊」的位點,是個常被忽略的篩選。
| 原始機率 raw | raw 矩陣 | binary 矩陣 | 含義 |
|---|---|---|---|
| 無覆蓋(−1.0) | NaN | −1 | 這條 read 根本沒讀到這個 CpG |
| ≥ 0.8 | 原值 | 1 | 甲基化 |
| ≤ 0.2 | 原值 | 0 | 未甲基化 |
| 0.2 – 0.8(灰帶) | 原值(保留) | −1 | 模糊:二值距離丟、Bernoulli 軟降權(詳見 §⑤) |
在甲基讀取「之前與之後」,ISM 有一串守門。下圖是漏斗,下表是每一關的門檻與源碼。
UNKNOWN(沒覆蓋到 SNV)也保留,因為它的甲基資訊對 normal-anchored 基線有用(ReadAggregator.cpp:46-55)。這就是為什麼 normal BAM 是 ISM 的重要輸入。alt_support==UNKNOWN(沒蓋到 SNV 位)的 tumor read 丟;normal 不丟。ReadAggregator.cpp:49‑55read_name 只留第一條。ReadAggregator.cpp:57‑60① min_site_coverage = 5(「每個 CpG 至少 5 條 read 覆蓋才保留該欄」):在 Config.hpp:36 宣告,但 grep src/ include/ 全域只有這一處宣告、無任何使用點(2026‑06‑13 驗)。屬預留 / 殘留參數 — 從程式碼無法判定是「刻意停用」或「未接線殘留」(標 undetermined,非指控疏失)。實務含義:現行矩陣建構不做 per‑CpG 覆蓋過濾,對外不可宣稱有此步。per-site cohort coverage 與 pairwise Cmin 是不同 gate,對現有結論的影響為 UNVERIFIED,需接線後做 sensitivity rerun 才能判定。(若日後接線需更新本頁)
② PMD gating(pmd_gating=true, pmd_bed_path;PMD=partially methylated domain 部分甲基化區,非 post-mortem damage):同樣只在 Config.hpp 與 config receipt serializer 出現,核心路徑沒有 CLI/filter wiring。屬declared-but-unwired,不是可用 optional feature;預設旗標雖為 true,現行也不會實際套用 PMD BED。
這兩條是 §13.0「先有驗證過的事實才寫」的範例:與其寫「合理推測有做」,不如誠實標「宣告未接線」。
矩陣建好後,算每對 read 的距離。這裡有第三種「篩選」— 共同覆蓋不足的 read 對被判無效。ISM 實作了 6 種距離;有效 CLI 無參數預設是 NHD,BERNOULLI 只在明示指定時使用。
| 距離 | 用哪個矩陣 | 怎麼處理灰帶 | 一句話 |
|---|---|---|---|
| NHD 有效無參數預設 | binary | 灰帶=−1 → 丟 | 不一致位點 / 共同位點(最直覺) |
| BERNOULLI 需明示指定 | raw 機率 | 保留,用 2|p−0.5| 降權 | 期望不一致率,按信心加權 |
| L1 / L2 | raw | 保留 | 機率差的平均 / 均方根 |
| CORR | raw | 保留(需 ≥3 點) | 1 − 皮爾森相關 |
| JACCARD | binary | 灰帶=−1 → 丟 | 甲基位點集合重疊度 |
DistanceMatrix.cpp:237‑252),Bernoulli「用原始機率 + 信心權重,降低 p≈0.5 低信心位點的影響」。好處:保留 basecaller 的機率資訊;代價是比 NHD 多算權重、較不直覺。這是可選路徑,不是目前 CLI 預設。每對 read 必須有 ≥ Cmin 個「兩者都有效」的共同 CpG 才算得出距離;不足則該對標記為無效。effective current CLI 預設使用 SKIP 排除無效對;MAX_DIST=1.0 只是 legacy/experimental 選項,不是無參數生產行為。
| 參數 | 生產值 | 來源 | 備註 |
|---|---|---|---|
| Cmin(min_common_coverage) | 3 | Config.hpp:37 → RegionProcessor.cpp:790 | DistanceConfig internal initializer 是 5,但被 current Config 的 3 覆寫 |
| 無效對策略 | SKIP | Config.hpp:39 → RegionProcessor.cpp:791 | 不足 Cmin → 標記 invalid 並排除 |
| legacy/experimental max_distance_value | 1.0 | Config.hpp | 只在明示選 MAX_DIST 時視為「最遠」;非 effective default |
| 主距離 metric | NHD(無 CLI 參數) | ArgParser.hpp:181‑194 | Config.hpp:40 的 BERNOULLI initializer 會被清空;BERNOULLI 需明示指定 |
距離矩陣 → UPGMA 聚類 → 顯著性檢定。本頁專注「讀與篩」,這裡只點出與「篩選/可靠度」相關的關卡;完整在 ISM 方法本體。
| 關卡 | 做什麼 | 篩選/可靠度角色 | 來源 |
|---|---|---|---|
| reliability flag/summary projection | HP label × cluster 列聯表做 Cochran 檢查(≥80% 格期望 ≥5) | 不夠飽 → reliability=false、summary V=0;raw V 與 legacy gate 另保留,只約束 cluster × label association strength | MathUtils.cpp::cramers_v + RegionProcessor.cpp summary projection |
| PERMANOVA | 置換檢定指定 HP label 與 read-distance variation/centroid separation 的 association | n_permutations=999、seed=42;現行 p-floor=0.001;須合讀 PERMDISP,不證明 cluster truth | src/core/RegionProcessor.cpp(structure_config.n_permutations) |
| GlobalTest / LocalTest / PerCpgAsm | cluster × label 或 per-CpG label × methylation association | Fisher/Cramér's V 只量 association,非 truth、cellular group、causality 或單一 filter | SignificanceAnalyzer |
註:這些檢定量的是指定 label 與 read-distance variation、algorithmic cluster 或 per-CpG methylation 的 association,不是 unsupervised cluster existence/truth、cellular group、因果,也不是「這個 somatic 呼叫對不對」。PERMANOVA 還須與 PERMDISP 合讀;把 association 升格為 truth,正是 §⑦ 要避免的誤讀。
前面六節都是「處理層」。這節是完全不同的問題:已測的甲基特徵與資料切分,能否形成可用的 somatic TP/FP filter? 多重驗證在該 scope 下為 negative。這限制的是已測 formulation,不排除 materially new hypothesis。
| # | 驗證 | 結果 | 機制 / 為何失敗 | 來源 |
|---|---|---|---|---|
| 1 | 甲基增強 FP filter pilot(HCC1395 單樣本) | ΔF1=+0.00242 < ribbon | 在此模型中甲基訊號與 caller_af 高度重疊,未證明獨立增量軸 | 報告 20260518_V6_Methyl_Filter_Pilot |
| 2 | TP 救援(用甲基救回被丟的 TP) | TESTED NEGATIVE | 95.2% 流失 TP 是低 AF subclone(caller_af<0.3);已測救援規則同時重新引入 FP | 同上 Step 5c |
| 3 | 多軸 logistic regression 消融 | 甲基排第 5 | caller_af deviance 0.393 主導;甲基在該模型的增量貢獻最低 | 同上 H 機制 |
| 4 | LOSO 留一 + 全位點存在性掃描(6 樣本 28 萬位點) | 100% 循環 / 非 usable | TP 顯著率 3.95%(11655/294723) > FP 1.07%(34/3177) 但絕對靈敏度 ~4%、COLO829 TP≈FP | 報告 20260604_ISM_complete_TPFPFN |
在具名資料與既定比較軸中觀察到 scope-bound allele-associated methylation — BRCA2 的 observed HP-axis Δβ=−0.122、6/6 biological IDs 的 excess-over-null >0 跨 3 癌種(見 INDEX 的 ASM 卡)。這些 association 不證明 causal cis 或 tumor-acquired;而「觀察到 association」與「能告訴你這個 somatic 呼叫是真是假」也是兩個正交問題:
這個區分是本站「4 條鐵則」第 1 條,貫穿所有 ASM/甲基結論:association 不可升格為 truth 或 causality。
一張表把整頁收斂。教授若只看一張圖,看這張。
決定「什麼資料進矩陣 / 可比」。每次跑都在做。
狀態:正常前處理,確定性,無爭議。
想用甲基「判 somatic 呼叫真假」。提升 caller 精度。
狀態:已測 formulation concluded negative — 不升格成 universal claim;重開須新假說與 pre-decision audit。