圖 1: Locus QC 概念圖。系統架構圖,展示 DADA2、Merger、BLAST 數據匯入中心化資料庫,供推薦引擎使用並產出報告。
Locus 品質控制模組採用中心化資料庫架構,針對每個 locus 生成詳細的樣本級別報告,並整合序列推薦系統 (6 規則 + 可選 LLM);所有權威資料均以資料庫為準,CSV 與 FASTA 皆為匯出產物。主要功能:
- 針對每個 locus 聚合並輸出樣本級 QC 結果(資料庫為主,CSV 為匯出)
- 建立中心化 QC 資料庫 (
{locus}_qcReport.db) - 整合 6 規則序列推薦(前端勾選規則時,所有樣本統一進入 rule-as-judge → LLM 仲裁流程)
- 驗證與標準化樣本品質(生成 validation code)
- 統計並存放多階段 ASV / 讀長 / 比對指標(以程式碼欄位定義為準,無固定人工維護表格)
- 產生推薦序列 FASTA 檔案供後續分析
- 提供透明可追蹤之來源、規則、信心度與(如有)
recommendation_llm_model
核心遵循「資料庫為唯一權威」與「流程一次性重建」:
- 資料庫優先:所有查詢 / 驗證 / 推薦皆讀取
{locus}_qcReport.db;CSV 僅供人工閱讀或下游非程式化工具使用。 - 欄位集中定義:實際欄位集合由
QCSchemaManager.MAIN_QC_FIELDS管理(目前程式碼定義為 50 欄;CSV 會排除部份 hash / 技術欄位,因此顯示欄位數 < 定義總數,文件不再寫死固定數字)。 - 完全重建:
collect_all_qc_data()執行時會刪除並重新建立該 locus 相關主表內容(不可假設保留舊資料)。 - 索引前置:ASV 序列元資料索引 (Step 0) 先建立
asv_sequences供後續比對與推薦。 - 推薦內嵌:推薦引擎直接寫入主 QC 表欄位(非獨立側表)。
- 延遲載入序列:僅儲存序列 MD5 截斷 hash(或由其他結構追蹤),完整序列需於需要時再從原檔案載入。
- LLM 按需 & 可關閉:前端勾選規則時,樣本經 rule-as-judge 品質過濾後,若有多個候選序列,則可能呼叫 LLM;可完全停用。
- 明確信心策略:規則給定初始信心;Rule 1 若伴隨特定警告(如 6-1)將降級;LLM 失敗採 Fallback(比較 DADA2 與 Merger 最高豐度 ASV,取絕對較高者,固定信心 0.30)。
- 錯誤與缺失標記:任一來源缺失或計算失敗以 "N/A" 表示(利於外部過濾),不嘗試以 0 冒充有效數值。
一致性檢查:文件、CSV 欄位數或說明若與
constants.QCSchemaManager產生差異,以程式碼為準。
Locus QC 模組在整體 QC 完成後執行,負責樣本級別的詳細分析與推薦:
graph TD
A[整體 QC 完成] --> B[QCDataManager 初始化]
B --> C[collect_all_qc_data 資料收集]
C --> IDX[SequenceIndexer 建立索引]
IDX --> ASV["asv_sequences (metadata index)"]
ASV -->|lazy-load| F[推薦序列 FASTA 生成]
C --> D[SequenceRecommendationEngine 推薦引擎]
D --> E[推薦結果整合至資料庫]
E --> F
style A fill:#e8f5e8
style B fill:#fff3e0
style D fill:#f3e5f5
style IDX fill:#fff8e1
style ASV fill:#e8f5e8
執行特色:
- 承接整體統計:基於整體 QC 提供的基礎資訊進行樣本級分析
- 中心化管理:所有樣本資料統一管理於 SQLite 資料庫
- 推薦系統整合:原生整合 6 規則推薦引擎與 LLM 仲裁機制
核心控制器,負責統一管理 {locus}_qcReport.db 資料庫,位於 src/qc/qc_data_manager.py:
主要功能:
collect_all_qc_data():完整的資料收集引擎(主要入口點),執行概要:- 步驟 0:
index_denoise_sequences_to_database()- 將 denoise/ASV 序列的元資料索引進 SQLite(僅儲存元資料與索引,不儲存完整序列),並避免重複索引。 - 步驟 1-4:樣本資料收集、檔案統計、BLAST 結果整合與豐度分析,最後批次寫入資料庫。
- 步驟 0:
主要已實作的方法(位於 src/qc/qc_data_manager.py):
get_sample_mappings():回傳 barcode -> sample_name 映射(資料庫或解析結果取得)。get_denoise_parse_result():以DenoiseFileParser解析denoise_pairs.txt,回傳 ParseResult(含 samples 與 barcode_mapping)。index_denoise_sequences_to_database():建立asv_sequences索引(會清除該 locus 的舊索引並重新索引)。collect_all_qc_data():以 denoise_pairs.txt 為基準,使用 ThreadPoolExecutor 平行收集單樣本 QC 資料並批次插入資料庫。get_sample_data(sample_name):查詢單一樣本完整資料(回傳 dict 或 None)。get_all_samples():查詢所有樣本資料(回傳 List[dict])。update_sample_recommendation(sample_name, source, sequence, header, confidence, reasoning, llm_model=None):更新單一樣本的推薦欄位,並將recommendation_timestamp設為 CURRENT_TIMESTAMP。export_csv(output_path):匯出 CSV(雙層表頭),實作會使用QCSchemaManager.get_csv_headers('main')過濾不需顯示的欄位並將資料寫入檔案。
資料庫架構特點:
- SQLite 資料庫提供 ACID 交易支援
- 50 欄位完整樣本資料結構(含推薦結果)
- 增量更新機制,避免重複計算
- 檔案修改時間追蹤,確保資料時效性
統一推薦引擎,整合至 QC 流程中,位於 src/qc/recommendation_engine.py:
核心運作流程:
graph TD
A["開始 generate_recommendations"] --> RULES
RULES --> D[Rule-based judge 品質過濾]
E{品質過濾結果}
E -->|全拒絕| F[品質過濾失敗 Fallback<br/>回傳最高豐度]
E -->|唯一合格序列| G[直接推薦]
E -->|多個合格序列| H{是否有規則被勾選?}
H -->|是| I{LLM 是否可用?}
H -->|否| J[Fallback<br/>選最高豐度]
I -->|是| K[LLM 仲裁]
I -->|否| L[Fallback<br/>選最高豐度]
K --> M{LLM 結果}
M -->|成功| N[LLM 推薦]
M -->|失敗| O[Fallback<br/>選最高豐度]
F --> P[儲存推薦結果]
G --> P
J --> P
L --> P
N --> P
O --> P
P --> Q[提取推薦序列]
Q --> R[結束]
%% 規則分類詳情
subgraph RULES["Rule 分類模組"]
direction TB
S["Rule 1: identical 含 1<br/>(Merger Top1 命中 DADA2 Top-K)"]
T["Rule 2: identical 含 2..K 且不含 1"]
U["Rule 3: 其餘情況<br/>(N/A / Error / 空值 / >K)"]
V[Rule 4: DADA2 失敗但 Merger 有序列]
W[Rule 5: DADA2 有序列但 Merger 失敗]
X[Rule 6: 雙重失敗]
end
%% 品質過濾詳情
subgraph FILTERS["雙層過濾機制"]
direction TB
Z["低豐度排除<br/>(Low-Abundance Filtering)<br/>Proportion <= 0.10"]
AA["高豐度採納<br/>(High-Abundance Acceptance)<br/>Proportion >= 0.85"]
end
D --> FILTERS
FILTERS --> E
Rule-as-Judge 採用分層過濾策略以減少 LLM 呼叫並提升效率:
graph TD
A["樣本資料<br/>(DADA2 + Merger)"] --> B{高豐度採納<br/>Proportion >= 0.85?}
B -->|是| C["高豐度採納通過<br/>直接推薦"]
C --> END1["推薦該序列<br/>跳過 LLM"]
B -->|否| D{低豐度排除<br/>已檢查?}
D -->|已檢查| E["應用低豐度排除<br/>移除 proportion<br/><= min_relative_proportion<br/>預設 0.10 之序列"]
E --> G{過濾後<br/>剩餘序列數}
G -->|0 個| H["品質過濾失敗<br/>回傳最高豐度"]
G -->|1 個| I["唯一通過<br/>直接推薦"]
G -->|2+ 個| J["標記 INCONCLUSIVE<br/>需要 LLM 仲裁"]
H --> END2["推薦最高豐度<br/>供人工檢視"]
I --> END3["直接推薦"]
J --> END4["進入 LLM 仲裁"]
style B fill:#fff9c4
style D fill:#fff9c4
style C fill:#c8e6c9
style I fill:#c8e6c9
style H fill:#ffccbc
style J fill:#f3e5f5
雙層過濾機制 - 參數對照表:
| 機制名稱 | 程式碼參數 | 型態 | 預設值 | 說明 |
|---|---|---|---|---|
| 低豐度排除 (Low-Abundance Filtering) | enable_model_a |
bool | True | 啟用低豐度排除機制,移除相對豐度 <= 0.10 的序列 |
min_relative_proportion |
float | 0.10 | 低豐度排除閾值 | |
| 高豐度採納 (High-Abundance Acceptance) | enable_model_b |
bool | False | 啟用高豐度採納機制,相對豐度 >= 0.85 時直接推薦 |
high_confidence_proportion |
float | 0.85 | 高豐度採納閾值 |
實作原則:
- 高豐度採納優先:若啟用且序列相對豐度 >= 0.85,直接推薦,跳過後續過濾與 LLM
- 低豐度排除次之:若高豐度採納未觸發,則應用低豐度排除,移除相對豐度 <= 0.10 的序列
- 順序決策:優先執行高豐度採納;失敗則執行低豐度排除;都失敗則進入 LLM 仲裁
QC-Only 模式支援從先前批次重用 LLM 分析結果以節省成本:
graph TD
A["啟動 QC-Only 模式<br/>--start-from qc --source-batch batch_name"] --> B{llm_log_reuse<br/>啟用?}
B -->|否| C["進入常規流程<br/>即時 LLM 分析"]
B -->|是| D["查詢 llm_source_path<br/>下是否存在對應 sample<br/>的先前 LLM 結果"]
D --> E{結果找到?<br/>例如<br/>_majority_vote_summary.json}
E -->|是| F["載入該結果<br/>檢查 sample id<br/>與 locus 是否匹配"]
E -->|否| G["無先前結果<br/>進入常規流程"]
F --> H{映射<br/>安全?}
H -->|是| I["重用該 LLM 結果<br/>解析 selected_sequence_id<br/>載入對應序列"]
H -->|否| J["映射失敗<br/>進入常規流程"]
I --> K["推薦應用<br/>信心度延用舊結果<br/>或程式預設"]
G --> L["呼叫即時 LLM<br/>或 fallback"]
J --> L
K --> M["儲存推薦至 DB<br/>recommendation_llm_model 不更新<br/>(延用舊値或標記 log_reuse)"]
L --> M
style A fill:#fff3e0
style D fill:#fff9c4
style I fill:#c8e6c9
style K fill:#c8e6c9
style L fill:#f3e5f5
LLM 日誌重用配置:
recommendation:
llm_log_reuse: true
llm_source_path: "/path/to/previous_batch/llm_logs"CLI 使用範例:
python src/powerBarcode.py --start-from qc --source-batch previous_batch_name整合高豐度採納、低豐度排除、LLM、fallback 的完整決策邏輯:
graph TD
A["樣本<br/>(DADA2/Merger)"] --> B["Rule-as-Judge<br/>高豐度採納 → 低豐度排除"]
B --> C{品質過濾<br/>結果}
C -->|全拒絕| D["返回最高豐度<br/>供人工檢視"]
C -->|唯一序列<br/>通過| E{是否有<br/>警告?<br/>例如 Warning 6-1}
C -->|多序列<br/>INCONCLUSIVE| F{前端是否<br/>勾選規則?}
E -->|是| E1["直接推薦<br/>標記為<br/>需人工檢視"]
E -->|否| E2["直接推薦"]
F -->|否| F1["Fallback<br/>選最高豐度"]
F -->|是| G{LLM<br/>可用?}
G -->|否| G1["Fallback<br/>選最高豐度"]
G -->|是| H{嘗試<br/>llm_log_reuse?}
H -->|是| H1["載入舊 LLM 結果"]
H -->|否| H2["即時呼叫 LLM"]
H1 --> I{載入<br/>成功?}
H2 --> I
I -->|是| I1["使用 LLM 結果"]
I -->|失敗| I2["Fallback<br/>選最高豐度"]
D --> J["儲存至 DB<br/>更新欄位"]
E1 --> J
E2 --> J
F1 --> J
G1 --> J
I1 --> J
I2 --> J
J --> K["生成推薦 FASTA"]
K --> L["結束"]
style B fill:#fff8e1
style C fill:#ffe0b2
style E1 fill:#c8e6c9
style E2 fill:#c8e6c9
style F1 fill:#ffccbc
style I1 fill:#c8e6c9
style I2 fill:#ffccbc
style D fill:#ffccbc
style J fill:#f3e5f5
流程圖說明與實作差異註記:
- 前端勾選分流:核心決策點。是否勾選任何規則,決定是否進入 LLM 仲裁;未勾選則走傳統保守流程。
- 規則分類僅為統計:
_classify_sample_by_rules(Rule 1-6)僅用於分類統計與追溯,實際決策完全由Rule-based judge的過濾結果驅動。 - 統一品質過濾:所有樣本一律先經
Rule-based judge品質過濾(相對豐度比例 proportion),此步驟判斷是否能直接決策。 - 過濾結果驅動決策:
- 品質過濾全拒絕:走「品質過濾失敗 Fallback」,回傳最高豐度序列供人工檢視。
- 唯一合格:直接推薦;若有警告(如 Warning 6-1 或低絕對豐度)則標記為需人工檢視。
- 多個合格:需 LLM 仲裁。
- 仲裁方式由模式決定:
- 未勾選規則(傳統保守):不呼叫 LLM,直接選擇 DADA2 與 Merger 中「絕對豐度較高」的一方。
- 有勾選規則(統一仲裁):嘗試呼叫 LLM;成功則採用 LLM;失敗則回退至傳統 Fallback(最高豐度)。
- LLM 仲裁的 Top1/Top2 規約:引擎並不在呼叫 LLM 前主動「傳遞候選列表」。LLM pipeline 以 locus+sample 為鍵進行分析並在輸出中給出
selected_sequence_id(如dada2_top1、merger_top2),引擎再依此透過_get_dada2_sequence_by_rank/_get_merger_sequence_by_rank載入對應序列。
主要功能:
-
generate_recommendations():主入口點,完整的兩階段推薦流程階段 1:規則分類(Step 1)
-
遍歷所有樣本,呼叫
_classify_sample_by_rules()進行規則判定,僅為統計目的。 -
輸出規則分類統計。
階段 2:推薦處理(Step 2)
- 由單一入口
_process_sample(...)完成分流:- 先走
Rule-based judge。 - 唯一合格 → 直接推薦(不呼叫 LLM)。
- 多個合格 → 若前端有勾選規則且 LLM 可用則仲裁;否則 fallback(最高豐度)。
- 先走
- 每處理完一個樣本即呼叫
_save_recommendation_to_db()儲存。 - 進度輸出:日誌包含處理索引
(idx/total)。
- 由單一入口
-
-
_classify_sample_by_rules(sample_data):6 規則分類邏輯規則判定順序:
1. 檢查序列存在性(has_dada2, has_merger) ├─ 雙無 → Rule 6(雙重失敗) ├─ 僅 Merger → Rule 4(DADA2 失敗,DADA2 失敗但 Merger 有序列) └─ 僅 DADA2 → Rule 5(Merger 失敗,DADA2 有序列但 Merger 失敗) 2. 雙有情況下,解析 identical_to_topK_dada2_merge ├─ 包含 "1" → Rule 1(Merger Top1 命中 DADA2 Top-K) ├─ 包含 2~K 且不含 1 → Rule 2(Merger 其他高豐度候選命中 DADA2 Top-K) └─ N/A / Error / 空值 / >K → Rule 3(無有效交集訊號)實作細節:
- 使用
_has_dada2_sequence_in_db()與_has_merger_sequence_in_db()檢查序列 - 支援逗號分隔的多值欄位(如 "1,3,5")
- 容錯處理:N/A、Error、空值等異常狀況統一歸類為 Rule 3
- 使用
-
_process_sample(sample_id, sample_data, rule, enable_llm, ...):統一處理流程執行步驟:
Step 1:Rule-based judge 品質過濾
# rule_judge.evaluate_sample() 返回品質過濾結果 rule_result = self.rule_judge.evaluate_sample(sample_data, sample_id)
- 呼叫
RuleJudge.evaluate_sample()進行雙層過濾。 - 過濾機制(簡化設計):僅使用 相對豐度比例 (proportion) 進行決策
- 高豐度採納 (High-Abundance Acceptance):若序列 proportion >= 0.85,直接推薦
- 低豐度排除 (Low-Abundance Filtering):移除 proportion <= 0.10 的序列
- 輸出:包含決策標誌、指標等資訊的結果物件。
decision:MERGER_PREFERRED、DADA2_PREFERRED 或 INCONCLUSIVEmetrics:過濾後的序列計數與拒絕理由- 內部追蹤值(如信心度)供後續決策分流使用
Step 2:根據品質過濾結果進行決策分流
-
品質過濾全拒絕:沒有任何合格序列。
- 決策:使用品質過濾失敗 fallback,回傳最高豐度序列供人工檢視。
- 統計:
rule_{rule}_quality_filter_rejected_count
-
品質過濾直接決策:品質過濾成功且只有一個合格序列。
- 決策:直接推薦該序列(無需 LLM)。
- 統計:
rule_{rule}_direct_merger_count或rule_{rule}_direct_dada2_count
-
品質過濾多序列INCONCLUSIVE:品質過濾成功但有多個合格序列。
- 特殊檢查:如果過濾後只剩下兩個序列且完全相同。
- 條件:
passed_sequences == 2且passed_dada2 == 1且passed_merger == 1且序列完全一致。 - 決策:依豐度選擇來源(無需 LLM)。
- 統計:
rule_{rule}_identical_sequences_count
- 條件:
- 一般情況:有多個合格序列且不完全相同。
- 決策:進入 LLM 仲裁階段(若啟用)或使用 fallback。
- 統計:
rule_{rule}_judgment_inconclusive_count
Step 3:LLM 仲裁(若啟用且有多個合格序列)
- 呼叫
llm_pipeline.run_single_sample_analysis(locus, sample_id)。 - Pipeline 於輸出中提供
selected_sequence_id(如dada2_top1、merger_top2)。 - 引擎據此呼叫
_get_dada2_sequence_by_rank/_get_merger_sequence_by_rank萃取對應序列,並透過_process_llm_result()統一產生推薦。 - 任一環節失敗或 LLM 不可用 → Fallback(於 DADA2 與 Merger 的「最高豐度」之間選擇絕對值較大者)。
- 特殊檢查:如果過濾後只剩下兩個序列且完全相同。
統計追蹤(與處理流程完全對應):
rule_{rule}_quality_filter_rejected_count: 品質過濾失敗的次數rule_{rule}_direct_merger_count: 直接選擇 Merger 的次數rule_{rule}_direct_dada2_count: 直接選擇 DADA2 的次數rule_{rule}_identical_sequences_count: 兩個序列完全相同,依豐度選擇的次數rule_{rule}_judgment_inconclusive_count: 多個序列需要 LLM 仲裁的次數rule_{rule}_llm_count: 實際執行 LLM 仲裁的次數llm_fallback_count:LLM 失敗回退的次數
其他:
- Rule 6(雙重失敗)會在品質過濾前就被分類統計;實際上推薦決策仍由
Rule-based judge與後續分流決定。若品質過濾全拒絕,將走「品質過濾失敗 Fallback」。
- 呼叫
-
_save_recommendation_to_db(sample_id, recommendation):即時儲存推薦結果- 每處理完一個樣本立即更新資料庫(非批次更新)。
- 更新欄位:
recommendation_sourcerecommendation_sequencerecommendation_headerrecommendation_confidencerecommendation_reasoningrecommendation_llm_model(若適用)recommendation_timestamp(自動設為 CURRENT_TIMESTAMP)
-
_extract_recommended_sequences(recommendations):萃取推薦序列並生成 FASTA(.fas)- 若推薦含原始 header(多數情況),則直接保留該 header;否則使用
>sample_id|source=...|rule=...形式。 - 所有「有實際序列內容」的推薦都會輸出;若無序列則輸出
# 無可用序列行作為占位。
- 若推薦含原始 header(多數情況),則直接保留該 header;否則使用
推薦決策核心邏輯:
- 所有樣本先經 Rule-based Judge 品質過濾(高豐度採納 → 低豐度排除)
- 過濾結果分流:全拒絕 → Fallback;唯一合格 → 直接推薦;多合格 → LLM 仲裁或傳統 Fallback
- LLM 僅在配置允許且 rule-as-judge 判定為多序列不一致時呼叫
- 所有推薦結果立即持久化至資料庫,包含來源、序列、規則追溯等資訊
LLM 整合特點:
- 按需啟用:僅在
Rule-based judge判定「多個合格」且前端有勾選規則時才呼叫。 - 可完全停用:
config.llm_analysis_enabled=False。 - 智慧回退:LLM 失敗或未啟用時使用傳統 Fallback(最高豐度優先)。
- 進度追蹤:日誌輸出包含
(idx/total)。 - 報告生成:Pipeline 負責;引擎僅解析結果。
- 使用中的方法:
_process_sample(...):單一入口,統一分流。_process_llm_result(...):解析selected_sequence_id(如dada2_top1)。_select_highest_abundance_asv_fallback(...):一般 Fallback。_save_recommendation_to_db(...):寫入推薦欄位(含recommendation_llm_model)。_extract_recommended_sequences(...):輸出 FASTA;若原 header 存在則保留。
設計特點:
- 兩階段處理(分類 → 處理),避免重複檢查並提升效率
- LLM 僅在配置允許且 rule-as-judge 無結論時才會被呼叫
- 確保推薦更新為原子性操作,避免資料不一致
- 支援透過參數或 config 過濾部分規則以調整行為
優化特色:
- 避免重複檢查:先分類再處理,消除 Rule 條件重複檢查
- 精確 LLM 控制:只有真正需要的樣本才進行 LLM 分析
- 提升整體效率:對大量樣本特別有效,減少不必要的計算
- 清晰的分工:每個步驟責任明確,便於除錯與維護
_classify_sample_by_rules() 依據合併來源與 identical_to_topK_dada2_merge(K 預設 = 2)結果進行分類:
| 規則 | 條件核心 | 判斷依據(摘要) | 處理策略 | 備註 |
|---|---|---|---|---|
| Rule 1 | 雙來源最高一致 | identical_to_topK_dada2_merge 含 1 |
一律先進 Rule-based judge,後續按合格數決策 |
僅作統計與追溯,不直接影響推薦 |
| Rule 2 | Top-K 交集(非首位) | identical_to_topK_dada2_merge 含 2..K |
同上 | 同上 |
| Rule 3 | 無交集但雙方都有序列 | identical_to_topK_dada2_merge 為空/N/A/Error |
同上 | 同上 |
| Rule 4 | 僅 Merger 有序列 | DADA2 無序列, Merger 有序列 | 同上 | 同上 |
| Rule 5 | 僅 DADA2 有序列 | Merger 無序列, DADA2 有序列 | 同上 | 同上 |
| Rule 6 | 皆失敗 | 兩者無序列 | 同上 | 同上 |
判斷補充:
identical_to_topK_dada2_merge記錄「Merger 中哪些 ASV(按豐度排序的 rank,1-based)」的 hash 出現在「DADA2 merge 前 K (預設 2) 個 ASV 的 hash 集合」中(逗號分隔)。例如"1"表示 Merger 第1名的 hash 出現在 DADA2 top K 集合中(不一定是 DADA2 的第1名)。- 空字串 / None / "N/A" / "Error" 等皆視為「無交集」。
- 與 Warning 12-1(DADA2 Highest Abundance ASV 超過前三名)為不同概念;Warning 12-1 使用固定閾值 3,而推薦系統此處的 K 可調整(預設 2)。
品質問題判定:
- Warning 6-1:DADA2 r1/r2 abundance 比例懸殊
- 低豐度:DADA2 r1/r2 比例正常但絕對數值偏低(< 50)
- 單序列通過:rule-as-judge 直接決策,屬於高信心度情形
- 多序列通過:需要 LLM 仲裁或傳統 Fallback,屬於低信心度情形
LLM 輸出來源正規化(以程式碼為準):
- LLM 輸出
selected_sequence_id,格式如dada2_top1、merger_top2。 - 引擎直接將
source設為該值,並以對應的 rank 載入序列;不會自動改寫為單純dada2/merger。 - 若解析失敗則回退一般 Fallback。
系統自動將所有推薦結果彙整為 {locus}_recommended_sequences.fas:
檔案格式:
>{sample_id}|source={推薦來源}|rule={規則編號}
序列內容
範例輸出:
>sample001|source=merger|rule=1
ATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCG
>sample002|source=dada2_top1|rule=3
GCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCT
>sample003|source=dada2|rule=5
TTAACCGGTTAACCGGTTAACCGGTTAACCGGTTAACCGGTTAACCGGTTAACCGGTTAACCGGTTAACCGG
>sample004|source=merger|rule=6
# 無可用序列
系統架構與資料流:
flowchart TD
A[PowerBarcoder 主流程] --> B[Demultiplex]
B --> C[DADA2 Denoise]
C --> D[DADA2 Merge & 10N Concat]
D --> E[Merger Pipeline]
E --> F[統一 QC 與推薦處理]
F --> G["{locus}_qcReport.db"]
G --> H[SequenceRecommendationEngine]
H --> I[6 規則推薦系統]
I --> J[推薦決策輸出]
style G fill:#e8f5e8
style H fill:#fff3e0
style I fill:#f3e5f5
核心類別設計:
class SequenceRecommendationEngine:
"""序列推薦引擎"""
def __init__(self, locus: str, result_data_path: str):
self.qc_manager = QCDataManager(locus, result_data_path)
self.llm_results = self._load_llm_results()
def generate_recommendations(self) -> Dict[str, Dict]:
"""為所有樣本生成推薦"""
def _apply_recommendation_logic(self, sample_data: Dict) -> Dict:
"""應用推薦邏輯"""
def _integrate_llm_results(self, sample_id: str) -> Optional[Dict]:
"""整合 LLM 分析結果"""專注於純粹的資料解析功能,提供核心解析函數:
主要功能:
parsing_denoise_pair_into_dict():解析條碼與樣本名稱對應parsing_fastq_reads_number():統計 FASTQ 檔案讀取數量check_fasta_sequence_count():統計 FASTA 檔案內序列數量 (每個 ASV 一條序列)check_fasta_asv_file_count():統計 目錄內 ASV 檔案數量(每個 ASV 一個檔案)parsing_blast_result_into_dict():解析 BLAST 結果parse_highest_abundance_asv():解析豐度最高的 ASV 資訊calculate_dada2_merge_identity():計算 merger ASV 序列與 DADA2 merge 前三高豐度的 ASV 是否一致
負責品質驗證並生成 validation code,已完全整合至中心化架構:
設計原則:
- 統一驗證入口:透過
get_validation_codes()函數執行 - 標準化輸出:成功顯示 "PASS",失敗顯示具體警告代碼
- 完整容錯處理:對 "N/A" 值與資料缺失提供錯誤處理
整合流程:
# 在 QCDataManager 中的使用
sample_data = self._collect_sample_qc_data(barcode, sample_name)
validation_code = get_validation_codes(sample_data)graph TD
A[QCDataManager 初始化] --> B[資料庫初始化]
B --> C[collect_all_qc_data 資料收集]
C --> C0[步驟 0: index_denoise_sequences_to_database<br/>ASV 序列索引建立]
C0 --> D[步驟 1: 樣本對應解析]
D --> E[步驟 2: 檔案統計計算]
E --> F[步驟 3: ASV 豐度分析]
F --> G[步驟 4: BLAST 結果整合]
G --> H[SequenceRecommendationEngine]
H --> H1[Rule 1-6: 規則分類]
H --> H2[統一仲裁流程(所有樣本進入 Rule-based Judge)]
H --> H3[INCONCLUSIVE 且前端未啟用規則: 直接 Fallback(最高豐度)]
H1 --> I[推薦結果整合至資料庫]
H2 --> I
H3 --> I
I --> J[Validation 驗證]
J --> K[資料庫儲存]
K --> L[export_csv CSV 匯出(含推薦結果)]
L --> M[推薦序列 FASTA 生成]
style A fill:#e3f2fd
style C fill:#fff3e0
style C0 fill:#fff8e1
style H2 fill:#fff9c4
style I fill:#f3e5f5
style K fill:#e8f5e8
style L fill:#fff9c4
style M fill:#fce4ec
| 資料類型 | 解析函數 | 來源檔案 | 輸出格式 |
|---|---|---|---|
| 樣本對應 | parsing_denoise_pair_into_dict() |
denoise_pairs.txt |
Dict[條碼, 樣本名] |
| FASTQ 統計 | parsing_fastq_reads_number() |
demultiplexResult/ 各子目錄 |
讀取數量字串 |
| FASTA 統計 | check_fasta_sequence_count() |
denoiseResult/, mergeResult/ |
序列數量字串 |
| ASV 檔案統計 | check_fasta_asv_file_count() |
mergeResult/merger/r1Ref/, r2Ref/, merged/ |
ASV 檔案數量字串 |
| BLAST 結果 | parsing_blast_result_into_dict() |
{locus}_blastResult.txt + r1Ref/ + r2Ref/ |
Dict[樣本, BLAST資訊] |
| ASV 豐度 | parse_highest_abundance_asv() |
mergeResult/merger/merged/ |
ASV 詳細資訊 |
| 豐度統計 | process_dada2_abundance_data() |
abundance 檔案 | [數量, 比例, 數值, hash] |
| 推薦結果 | SequenceRecommendationEngine |
推薦引擎分析 | 推薦序列與理由 |
| 驗證碼 | get_validation_codes() |
整合後樣本資料 | validation code 字串 |
檔案名稱:{locus}_qcReport.db (SQLite3)
主表名稱:{locus}_qcReport
欄位來源:QCSchemaManager.MAIN_QC_FIELDS
Implementation notes
- 欄位定義集中於
src/qc/constants.py;若文件與程式碼不同,以程式碼為準。- 目前欄位組成:以
QCSchemaManager.MAIN_QC_FIELDS為準(目前為 50 欄,含id與推薦相關欄位);CSV 會排除 hash 與內部欄位後顯示較少欄位(即「顯示欄位數」≠ MAIN_QC_FIELDS 長度)。- 每次執行
collect_all_qc_data()會重新建立主表資料(delete + bulk insert)。尚未實作真正的差量 / 增量更新策略。- 推薦欄位:
recommendation_source,recommendation_header,recommendation_sequence,recommendation_confidence,recommendation_reasoning,recommendation_timestamp,recommendation_llm_model。- FASTA 匯出:
{resultDataPath}/{locus}_result/qcResult/{locus}_recommended_sequences.fassave_overall_qc_report只影響 overall 報告表(與本 locus 主表分離)。
| 欄位類別 | 欄位名稱 | 資料類型 | 說明 |
|---|---|---|---|
| 基本資訊 | id |
INTEGER PRIMARY KEY | 主鍵,自動遞增 |
barcode |
TEXT | 樣本條碼 | |
sample_name |
TEXT | 樣本名稱 | |
created_at |
TIMESTAMP | 資料建立時間 | |
| 分流與修剪 | cutadapt_demultiplex_r1/r2 |
INTEGER | 分流後讀數 |
cutadapt_trim_r1/r2 |
INTEGER | 修剪後讀數 | |
| DADA2 流程 | dada2_filter_r1/r2 |
INTEGER | 過濾後讀數 |
dada2_denoise_r1/r2 |
TEXT | 降噪後檔案 | |
dada2_merge |
TEXT | 合併檔案 | |
dada2_10n_concat |
TEXT | 10N 拼接檔案 | |
| Merger 流程 | merger_blast_r1/r2 |
TEXT | BLAST 比對檔案 |
merger_merge |
TEXT | Merger 合併檔案 | |
| ASV 分析 | highest_abundance_asv_* |
TEXT/INTEGER | 最高豐度 ASV 詳情 |
ambiguous_sites_number |
INTEGER | 模糊性位點數 | |
lowercase_sites_number |
INTEGER | 小寫位點數 | |
| BLAST 結果 | blast_subject_id |
TEXT | BLAST 主題 ID |
blast_identity |
TEXT | BLAST 相似度 | |
blast_length |
TEXT | BLAST 覆蓋長度 | |
| 比對分析 | identical_to_topK_dada2_merge |
TEXT | 關鍵比對指標 |
| 豐度統計 | dada2_*_asv_count |
INTEGER | 各步驟 ASV 數量 |
dada2_*_best_asv_proportion |
REAL | 最佳 ASV 比例 | |
dada2_*_best_asv_number |
INTEGER | 最佳 ASV 數量 | |
dada2_*_hash_value |
TEXT | Hash 值 | |
| 驗證碼 | validation_code |
TEXT | QC 驗證碼 |
| 欄位名稱 | 資料類型 | 說明 | 範例 |
|---|---|---|---|
recommendation_source |
TEXT | 推薦來源(merger/dada2/llm/manual_review) | merger |
recommendation_header |
TEXT | 原始或規則 / LLM 產生的 header | >sample001|source=... |
recommendation_sequence |
TEXT | 推薦序列(source=manual_review 時可能為空字串) | ATCG... |
recommendation_confidence |
REAL | 內部信心度追蹤值(見第 6 節技術實作層) | 0.9 |
recommendation_reasoning |
TEXT | 規則 + 警告 + LLM 推論摘要 | Rule 1 ... |
recommendation_timestamp |
TEXT | CURRENT_TIMESTAMP(插入時自動) | 2025-01-09 08:13:51 |
recommendation_llm_model |
TEXT | 只有 LLM 成功時填寫(如 gpt-4o-mini) | gpt-4o-mini |
現行程式碼聚焦於主 QC 表;舊文件提及的 qc_samples, file_metadata, processing_status 等多表分層暫未完全落地或僅部分概念化。若後續加入額外輔助表(例如快取檔案修改時間以支援增量),將在此區更新。現階段不應假設存在增量專用 metadata 表。
位於 src/qc/qc_data_manager.py,提供統一資料存取介面:
主要方法:
get_all_samples()→ 獲取所有樣本資料update_sample_recommendation()→ 更新樣本推薦結果export_to_csv()→ 匯出 CSV 報告force_rebuild_from_files()→ 強制重建資料庫get_sample_by_name()→ 依名稱查詢樣本
設計特點:
- 支援增量更新,避免重複處理
- 檔案修改時間追蹤機制
- 並行檔案處理能力
- ACID 交易支援
基於 src/llm/analysis_pipeline.py 的 LLMAnalysisPipeline 設計:
統一仲裁流程中的樣本處理:
- 樣本分類:
_classify_sample_by_rules()識別 Rule 1-6 - 流程判斷:當前端啟用規則時,所有樣本進入統一仲裁流程
- 品質過濾:調用
rule_judge.evaluate_sample()進行品質評估 - 即時分析:若結果為 INCONCLUSIVE 且 LLM 啟用,調用
LLMAnalysisPipeline.run_single_sample_analysis(locus, sample_id) - 結果處理:解析
llm_analysis.final_recommendation.best_result - 資料庫存儲:立即更新推薦結果至 QC 資料庫
- 步驟 0:
index_denoise_sequences_to_database()- 將 denoise/ASV 序列的元資料索引進 SQLite(僅儲存元資料與索引,不儲存完整序列),並避免重複索引。 - 步驟 1-4:樣本資料收集、檔案統計、BLAST 結果整合與豐度分析,最後批次寫入資料庫。
- 解析失敗:
status = "completed_with_parsing_error",嘗試使用部分結果 - LLM 失敗:自動 Fallback(比較最高絕對豐度),信心度 0.30
- 網路錯誤:重試機制 + 後備邏輯
精確控制策略:
- 統一仲裁流程:當前端啟用規則時,所有樣本進入 rule-as-judge 品質過濾
- INCONCLUSIVE 處理:只有 rule-as-judge 判定為 INCONCLUSIVE 的樣本才可能進入 LLM
- 即時處理:每個需要 LLM 的樣本立即分析,避免批次延遲
- 配置控制:
PowerBarcoderConfig.llm_analysis_enabled全域開關 - 模型選擇:
PowerBarcoderConfig.llm_model統一模型設定
信心度策略:
系統使用內部信心度機制進行決策路由與結果追蹤。信心度的具體值定義見第 6 節「技術實作層」,此處簡述邏輯:
- 高豐度採納直接推薦的序列獲得最高信心度
- 品質過濾唯一通過的序列獲得次高信心度
- LLM 成功仲裁的序列獲得中等信心度
- 傳統 Fallback(最高豐度選擇)獲得較低信心度
- 品質過濾全拒絕的情形獲得最低信心度
人工檢視機制:信心度較低或存在警告的樣本在報告中標記為需人工檢視,並提供詳細的推薦理由。序列匯出時,若無可用序列則輸出佔位符。
序列來源優先級:推薦邏輯已經確保每個樣本只會有一個推薦來源,避免衝突。
觸發時機:推薦引擎在 QC 流程的 run_locus_qc 階段中,執行於所有 LLM 以外的 QC 分析完成之後,執行 generate_csv_report 方法之前。
為了提升資料存取效能與記憶體使用效率,系統採用序列索引 (Sequence Indexing) 機制,將序列元數據與檔案偏移資訊儲存於資料庫中,而非直接儲存完整序列內容。
表名:asv_sequences
用於儲存所有序列的元數據與索引資訊:
| 欄位名稱 | 資料類型 | 說明 |
|---|---|---|
id |
INTEGER PRIMARY KEY | 主鍵,自動遞增 |
locus |
TEXT | 基因座名稱 (如 trnLF, rbcL) |
sample_name |
TEXT | 樣本名稱 |
source |
TEXT | 序列來源 (denoise_r1, denoise_r2, dada2_merge, merger_final 等) |
file_path |
TEXT | 原始 FASTA 檔案路徑 |
sequence_start_line |
INTEGER | 序列內容起始行號(0-based 或實作以檔案讀取邏輯計算;請以程式碼為準,目前內部採用「檔案行列索引基於實際 enumerate」結果) |
sequence_end_line |
INTEGER | 序列內容結束行號(同上) |
header |
TEXT | FASTA 標頭 |
sequence_length |
INTEGER | 序列長度 |
ambiguous_sites |
INTEGER | 模糊性位點數 (非 ATCG 字元) |
lowercase_sites |
INTEGER | 小寫位點數 (低品質區段) |
abundance |
INTEGER | 序列豐度 |
proportion |
REAL | 豐度比例 (0.0-1.0) |
asv_index |
INTEGER | ASV 索引編號(參考序列可能使用負值標記) |
hash_value |
TEXT | 序列 MD5(uppercase(sequence)) 前 16 字元(截斷) |
created_at |
TIMESTAMP | 索引建立時間 |
設計目的與注意事項:
- Metadata-only 儲存:不在資料庫內保存完整序列字串;
sequence欄位不存在(避免肥大)。 - 檔案偏移索引:行號用於後續 lazy-load;行號基底請以實作為準(避免文件硬編碼 1-based / 0-based)。
- 高效查詢:針對
locus,sample_name,source等條件優化。 - 記憶體節省:大量 ASV 情境下仍保持 DB 輕量。
- 來源追溯:保留原始檔案相對 / 絕對路徑。
- Hash 戰略:截斷 MD5 至 16 字元可在極低碰撞風險與儲存節省間取平衡;需完整確認再做交叉驗證時,可動態重新計算全長 MD5。
- asv_index 特殊值:參考集合或非標準來源(例如比對參考)可能使用負數作為標記,不代表錯誤。
當需要完整序列內容時,系統採用延遲載入 (Lazy Loading) 策略:
載入流程:
- 元數據查詢:從
asv_sequences表取得file_path、sequence_start_line、sequence_end_line - 檔案讀取:使用
get_sequence_from_index()函數讀取指定行號範圍的序列內容 - 內容解析:提取 FASTA 格式的序列部分(去除標頭與換行符)
程式碼範例:
# 從資料庫查詢最高豐度 ASV 元數據
metadata = indexer.get_sequences_metadata(
locus="trnLF",
sample_name="sample001",
source="merger_final",
order_by_abundance=True,
limit=1
)[0]
# 延遲載入完整序列(僅在需要時)
if load_sequence:
sequence = get_sequence_from_index(
metadata.file_path,
metadata.sequence_start_line,
metadata.sequence_end_line
)效能優點:
- 按需載入:僅在真正需要序列內容時才讀取檔案
- 記憶體節省:避免預載大量序列資料
- I/O 優化:支援部分檔案讀取,減少磁碟存取量
索引建立時機:collect_all_qc_data() 中的 Step 0 呼叫 index_denoise_sequences_to_database() 先清空該 locus 既有索引再重建(目前沒有「僅新增差異」模式)。
執行順序:
def collect_all_qc_data(self):
"""完整的 QC 資料收集流程"""
try:
# 0. 在收集 QC 資料前,先索引 denoise 序列到資料庫(混合模式)
print(f"[INFO] 執行混合模式:索引 denoise 序列到資料庫")
self.index_denoise_sequences_to_database()
# 1. 取得 barcode-sample 對應關係和樣本清單
# 2. 收集實際處理結果(平行處理)
# 3. 批次插入資料庫
# ...其他步驟重建邏輯:
- 檢查現有索引:查詢
asv_sequences表中是否已有該 locus 的記錄 - 清除舊索引:若存在舊記錄,先刪除該 locus 的所有索引資料
- 重新掃描:遍歷所有相關 FASTA 檔案,解析序列元數據
- 批次插入:將新索引資料批次寫入資料庫
避免重複索引:透過「刪除該 locus 全部舊紀錄 → 重新掃描」策略達成;尚未實作檔案 modified_time 層級的細粒度增量。
流程特點:索引建立是所有後續資料收集與分析的基礎,會在樣本資料處理前完成
1. 查詢特定來源的 TOP K 序列:
# 取得 DADA2 merge 前 3 高豐度序列元數據
dada2_metadata = indexer.get_sequences_metadata(
locus="trnLF",
sample_name="sample001",
source="dada2_merge",
order_by_abundance=True,
limit=3
)2. 統計序列數量:
SELECT COUNT(*) FROM asv_sequences
WHERE locus = 'trnLF' AND sample_name = 'sample001' AND source = 'merger_final'3. Hash 值快速比對:
# 使用 hash_value 進行高效序列比對
dada2_hashes = {seq.hash_value for seq in dada2_metadata if seq.hash_value}
for merger_seq in merger_metadata:
if merger_seq.hash_value in dada2_hashes:
# 找到相同序列
identical_indices.append(merger_seq.asv_index)CSV 欄位並非寫死於文件,而是由 QCSchemaManager.get_csv_headers('main') 動態產生:
- 來源基礎:
MAIN_QC_FIELDS - 自動排除:
id,created_at與所有*_hash_value - 若未來新增欄位(例如新的品質指標),CSV 會自動反映;文件不再承諾固定欄位數字。
匯出報告邏輯區塊(概念分組):
處理階段統計區塊:
- Cutadapt demultiplex (r1/r2)
- Cutadapt trim (r1/r2)
- DADA2 filter (r1/r2)
- DADA2 denoise (r1/r2)
- DADA2 merge、DADA2 10N concat
- Merger blast (r1/r2)、Merger merge
分析結果區塊(ASV / 比對 / 比例):
- Highest Abundance ASV 詳細資訊(標頭、序列、品質指標)
- BLAST 比對結果
- DADA2/ASV 統計數據(各階段的 ASV 計數與豐度)
品質控制與推薦區塊:validation_code 與 recommendation_* 欄位(含 recommendation_llm_model)
資料缺失標記規則:任一來源缺失或檔案不存在,欄位值一律設為 "N/A";不以 0 冒充有效數值,避免誤判。
4.1.2.1 基本識別欄位
Barcode:條碼名稱,來自denoise_pairs.txt的 key(透過parsing_denoise_pair_into_dict()解析)Sample Name:樣本名稱,來自denoise_pairs.txt的 value
4.1.2.2 各處理階段統計欄位
1. Cutadapt demultiplex by sample barcode r1/r2:
- 資料來源:
demultiplexResult/untrimmed目錄下對應條碼的 FASTQ 檔案 - 計算邏輯:透過
parsing_fastq_reads_number()統計 reads 數量(每 4 行為 1 read) - 支援功能:模糊匹配檔案命名,處理多種命名格式
2. Cutadapt trim the primer sites r1/r2:
- 資料來源:
demultiplexResult/trimmed目錄下對應條碼的 FASTQ 檔案 - 計算邏輯:同上,統計修剪後的 reads 數量
3. DADA2 filter r1/r2:
- 資料來源:
demultiplexResult/filtered目錄下對應條碼的 FASTQ 檔案 - 計算邏輯:統計過濾後的 reads 數量
4. DADA2 denoise r1/r2:
- 資料來源:
denoiseResult/r1/和denoiseResult/r2/目錄下的 FASTA 檔案 - 計算邏輯:透過
check_fasta_sequence_count()計算 FASTA 檔案內的序列數量 - 檔案格式:支援
.fas和.fasta格式,使用 glob 模式匹配
5. DADA2 merge:
- 資料來源:
mergeResult/dada2/merged/目錄下的 FASTA 檔案 - 計算邏輯:計算合併後的序列數量
6. DADA2 10N concat:
- 資料來源:
mergeResult/merger/nCatR1R2/目錄下的 FASTA 檔案 - 計算邏輯:計算串聯後的序列數量
7. Merger blast r1/r2 與 Merger merge:
- 資料來源:
mergeResult/merger/r1Ref/、mergeResult/merger/r2Ref/和mergeResult/merger/merged/目錄下的 FASTA 檔案 - 計算邏輯:透過
check_fasta_asv_file_count()計算 ASV 檔案數量(每個 ASV 一個檔案的結構,與 DADA2 的單檔案多序列結構不同)
4.1.2.3 Highest Abundance ASV 欄位組
透過 parse_highest_abundance_asv() 函數,從 mergeResult/merger/merged/ 目錄分析豐度最高的 ASV:
- header:豐度最高 ASV 的 FASTA 標頭
- sequence:保持原始大小寫(小寫字母代表低品質區段)
- length:正確計算序列長度(去除換行符和空格)
- ambiguous sites number:序列中非 ATCG 字元數(如 R, Y, N 等)
- lowercase sites number:序列中小寫字母數量
- BLAST subjectID:透過
parsing_blast_result_into_dict()解析,支援智慧樣本名稱匹配 - Avg. BLAST identity:BLAST 比對相似百分比
- Avg. BLAST qstart-qend:BLAST 查詢序列起訖座標差
- Identical to Top K DADA2 merge:Highest Abundance ASV 於 DADA2 merge 結果中的所有相同序列位置(index,以逗號分隔)
4.1.2.4 BLAST 結果處理增強
基於 Highest Abundance ASV 的 BLAST 結果查詢,parsing_blast_result_into_dict() 實作精確的查詢邏輯:
處理流程:
- 讀取 BLAST 結果檔案並建立檔案名稱到結果的映射
- 根據樣本名稱找到 Highest Abundance ASV 檔案
- 使用 Highest Abundance ASV 的檔案名稱查找對應的 BLAST 結果
- 統一使用 BLAST 模組的標準計算方法:
- 建立 BlastEntry 物件包含完整 BLAST 資訊
- 使用 BlastPair.get_identity_score() 計算一致性分數
- 使用 BlastPair.get_coverage_length() 計算覆蓋長度(含 gap 懲罰)
- 回傳該 ASV 的 BLAST 資訊
- 若
BLAST subjectID、Avg. BLAST identity、Avg. BLAST qstart-qend欄位全部為空,則代表用於 merger merge 的 ASV,其豐度排序並非 Highest Abundance ASV。以 demo trnLF 為例,約有 31 條樣本會發生此情況,若 dada2 merge 效果依然不理想,建議人工檢視或透過推薦模組的統一仲裁流程(前端啟用規則時)進行品質過濾與可能的 LLM 仲裁。
計算邏輯:
- subject_id:Highest Abundance ASV 的 subject ID
- identity:使用 BLAST 模組標準方法重新計算的一致性比例
- length:使用 BLAST 模組標準方法計算的總覆蓋長度(含 gap 懲罰機制),在 QC 模組中統一稱為 length
4.1.2.5 DADA2/ASV 統計欄位組
每組三欄,分別對應 r1、r2、merge、10N concat,透過 process_dada2_abundance_data() 和 process_abundance_file() 計算:
- ASV count:該步驟產生的 ASV 數量(由 abundance 檔案的序列數量決定)
- best ASV proportion:豐度最高的 ASV 佔比(從標頭
_abundance_解析) - best ASV number:豐度最高的 ASV 數量(從標頭
_abundance_解析)
注意:hash value 欄位僅保留在資料庫中({locus}_qcReport.db),不再出現在 CSV 檔案({locus}_qcReport.csv)中,以簡化報告格式。
4.1.2.6 Validation Code 欄位
- 透過
validator.py模組自動生成 - 包含六大類品質檢查結果
- 成功樣本顯示 "PASS",失敗樣本顯示對應警告代碼
4.1.2.7 Recommendation 推薦結果欄位組
新增的推薦相關欄位:
- source:推薦來源(merger、dada2、manual_review)
- sequence:推薦序列內容
- confidence:推薦信心度(內部追蹤值,詳見第 6 節技術實作層)
- reasoning:推薦理由說明
- timestamp:推薦生成時間戳
中心化資料庫採用 SQLite 格式,包含以下主要表格:
- qc_samples:儲存所有樣本的完整 QC 資料(含推薦結果)
- file_metadata:追蹤檔案變更狀態(支援增量更新)
- processing_status:記錄處理狀態與錯誤資訊
- ACID 特性:確保資料一致性
- 增量更新:只處理變更的檔案
- 錯誤恢復:完整的事務回滾機制
- 高效查詢:建立適當索引提升查詢效能
除了 CSV 報告外,系統會自動生成 {locus}_recommended_sequences.fas 檔案,包含所有樣本的推薦序列:
檔案位置:{locus}_result/qcResult/{locus}_recommended_sequences.fas
標頭格式:
>{sample_id}|source={推薦來源}|rule={規則編號}
輸出範例:
>Pteris_edanyoi_KTHU2240|source=merger|rule=1
ATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCG
>Calymmodon_societatis_KTHU2084|source=dada2|rule=2
GCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCT
驗證器執行六大類品質檢查:
graph TD
A[sample_data 輸入] --> B[檢查資料完整性]
B --> C{資料是否為空}
C -->|是| D[回傳 FAIL_NO_DATA]
C -->|否| E[執行六類檢查]
E --> F[_check_low_read_numbers]
E --> G[_check_disproportionate_abundance]
E --> H[_check_merging_issues]
E --> I[_check_low_abundance_in_results]
E --> J[_check_convergence_denoising_issues]
E --> K[_check_blast_alignment_issues]
F --> L[合併所有警告代碼]
G --> L
H --> L
I --> L
J --> L
K --> L
L --> M{有警告代碼嗎}
M -->|否| N[回傳 PASS]
M -->|是| O[排序並去重]
O --> P[回傳逗號分隔的代碼字串]
Cutadapt 樣本條碼分流
- 警告 1-1:r1 分流後讀長數量過低(< 100)
- 警告 1-2:r2 分流後讀長數量過低(< 100)
Cutadapt 引子位點修剪
- 警告 2-1:r1 修剪後讀長數量過低(< 100)
- 警告 2-2:r2 修剪後讀長數量過低(< 100)
DADA2 過濾
- 警告 3-1:r1 DADA2 修剪後讀長數量過低(< 100)
- 警告 3-2:r2 DADA2 修剪後讀長數量過低(< 100)
DADA2 合併 — 讀長檢查
- 警告 7-1:合併讀長數量低於閾值(< 30)
- 警告 7-2-1:r1 合併讀長數量驟降(合併:r1 最佳 < 0.3)
- 警告 7-2-2:r2 合併讀長數量驟降(合併:r2 最佳 < 0.3)
DADA2 10N 拼接 — 讀長檢查
- 警告 9-1:10N 拼接讀長數量低於閾值(< 30)
Merger 合併 — 讀長檢查
- 警告 11-5:合併讀長數量低於閾值(< 30)
- 警告 11-6-1:r1 合併讀長數量驟降(合併:r1 最佳 < 0.3)
- 警告 11-6-2:r2 合併讀長數量驟降(合併:r2 最佳 < 0.3)
DADA2 合併 — 豐度/平衡檢查
- 警告 6-1:r1 與 r2 間豐度比例不平衡(可接受範圍:0.3 ~ 1.6)
- 警告 6-2:r1 相對豐度過高(最佳 r1 讀長 / 全部 r1 讀長 ≤ 0.5)
- 警告 6-3:r2 相對豐度過高(最佳 r2 讀長 / 全部 r2 讀長 ≤ 0.5)
DADA2 10N 拼接 — 豐度/平衡檢查
- 警告 8-1:r1 與 r2 間豐度比例不平衡(可接受範圍:0.3 ~ 1.6)
- 警告 8-2:r1 相對豐度過高(最佳 r1 讀長 / 全部 r1 讀長 ≤ 0.5)
- 警告 8-3:r2 相對豐度過高(最佳 r2 讀長 / 全部 r2 讀長 ≤ 0.5)
Merger 合併 — 豐度/平衡檢查
- 警告 11-2:r1 與 r2 間豐度比例不平衡(可接受範圍:0.3 ~ 1.6)
- 警告 11-3:r1 相對豐度過高(最佳 r1 讀長 / 全部 r1 讀長 ≤ 0.5)
- 警告 11-4:r2 相對豐度過高(最佳 r2 讀長 / 全部 r2 讀長 ≤ 0.5)
DADA2 合併 — 合併失敗檢查
- 警告 7-3:合併失敗
- 警告 7-4:至少一個方向(r1 或 r2)不是合併結果的子序列
Merger 合併 — 合併失敗檢查
- 警告 11-1:合併結果具有高模糊度(模糊位點 + 小寫位點 > 15)
- 警告 11-7:合併失敗
- 警告 11-8:至少一個方向(r1 或 r2)序列不是合併結果的子序列
DADA2 合併 — 結果豐度檢查
- 警告 7-2-0:合併結果豐度過低(≤ 0.5)
DADA2 10N 拼接 — 結果豐度檢查
- 警告 9-2:拼接結果豐度過低(≤ 0.5)
Merger 合併 — 結果豐度檢查
- 警告 11-6-0:合併結果豐度過低(≤ 0.5)
DADA2 錯誤學習
- 警告 4-1:R1 錯誤學習收斂失敗
- 警告 4-2:R2 錯誤學習收斂失敗
DADA2 去噪
- 警告 5-1:R1 ASV 去噪無法超過閾值(使用者指定閾值 > 30)
- 警告 5-2:R2 ASV 去噪無法超過閾值
Merger / DADA2 相關比對與位置
- 警告 10-1:BLAST 比對中未找到候選參考序列
- 警告 12-1:DADA2 比對/排名提示 - Highest Abundance ASV 不在前 3 名(任一位置 index > 3,閾值固定為 3)
區分說明:
identical_to_topK_dada2_merge(推薦系統用)只追蹤 Merger 最豐度序列是否出現在 DADA2 merge 前 K (預設 2) 名;Warning 12-1 則評估「DADA2 Highest Abundance ASV 是否掉出前三」。兩者 K 值與意義不同,請勿混淆。
| 驗證碼 | 分類 | 描述 | 觸發條件 |
|---|---|---|---|
| Warning 1-1/1-2 | 低讀長數量 | r1/r2 分流後讀長數量過低 | < 100 |
| Warning 2-1/2-2 | 低讀長數量 | r1/r2 修剪後讀長數量過低 | < 100 |
| Warning 3-1/3-2 | 低讀長數量 | r1/r2 DADA2 修剪後讀長數量過低 | < 100 |
| Warning 4-1/4-2 | 收斂性與去噪 | R1/R2 錯誤學習收斂失敗 | 收斂失敗 |
| Warning 5-1/5-2 | 收斂性與去噪 | R1/R2 ASV 去噪無法超過閾值 | < 30 |
| Warning 6-1/6-2/6-3 | 不平衡豐度 | DADA2 豐度比例問題 | 比例不在 0.3~1.6 或 ≤ 0.5 |
| Warning 7-1/7-2-1/7-2-2 | 低讀長數量 | DADA2 合併讀長問題 | < 30 或 < 0.3 倍 |
| Warning 7-2-0 | 結果豐度 | DADA2 合併結果豐度過低 | ≤ 0.5 |
| Warning 7-3/7-4 | 合併問題 | DADA2 合併失敗或方向序列問題 | 合併數量 = 0 或子序列檢查失敗 |
| Warning 8-1/8-2/8-3 | 不平衡豐度 | DADA2 10N 豐度比例問題 | 同 Warning 6 系列 |
| Warning 9-1/9-2 | 低讀長/結果豐度 | DADA2 10N 拼接問題 | < 30 或 ≤ 0.5 |
| Warning 10-1 | BLAST 比對 | 未找到候選參考序列 | 空值 |
| Warning 11-1~11-8 | Merger 相關 | Merger 各種問題 | 類似 DADA2 對應問題 |
| Warning 12-1 | 排名 / 比對 | DADA2 Highest Abundance ASV 不在前三 | 任一 index > 3 |
信心度降級:目前僅針對 Rule 1 且出現 Warning 6-1(豐度比例不平衡)進行降級(0.9→0.6);Warning 12-1 不直接影響信心度,但可記錄於 reasoning。
This document provides a comprehensive reference for all validation codes used in PowerBarcoder's quality control system. These codes are generated based on predefined thresholds and rules implemented in src/qc/validator.py.You can find the code in QcReport.csv under the validation_code column. The codes are categorized into warnings and errors based on the severity of the issues detected during various processing stages.
| Code | Description | Threshold |
|---|---|---|
| Warning 1-1 | Low read count after demultiplexing in R1 | < threshold (early stage) |
| Warning 1-2 | Low read count after demultiplexing in R2 | < threshold (early stage) |
| Warning 2-1 | Low read count after trimming in R1 | < threshold (early stage) |
| Warning 2-2 | Low read count after trimming in R2 | < threshold (early stage) |
| Warning 3-1 | Low read count after DADA2 filtering in R1 | < threshold (early stage) |
| Warning 3-2 | Low read count after DADA2 filtering in R2 | < threshold (early stage) |
| Warning 7-1 | Merged read count below threshold | < 30 reads |
| Warning 7-2-1 | Sudden drop in merged reads from R1 | merge/r1_best < threshold |
| Warning 7-2-2 | Sudden drop in merged reads from R2 | merge/r2_best < threshold |
| Warning 9-1 | 10N concatenated read count below threshold | < 30 reads |
| Warning 11-5 | Merger merged read count below threshold | < 30 reads |
| Warning 11-6-1 | Sudden drop in merger reads from R1 | merge/r1_best < threshold |
| Warning 11-6-2 | Sudden drop in merger reads from R2 | merge/r2_best < threshold |
| Code | Description | Threshold |
|---|---|---|
| Warning 6-1 | Disproportionate abundance ratio R1/R2 (DADA2 merge) | Outside 0.3-1.6 range |
| Warning 6-2 | High relative abundance in R1 (DADA2 merge) | > 0.9 |
| Warning 6-3 | High relative abundance in R2 (DADA2 merge) | > 0.9 |
| Warning 8-1 | Disproportionate abundance ratio R1/R2 (10N concat) | Outside 0.3-1.6 range |
| Warning 8-2 | High relative abundance in R1 (10N concat) | > 0.9 |
| Warning 8-3 | High relative abundance in R2 (10N concat) | > 0.9 |
| Warning 11-2 | Disproportionate abundance ratio R1/R2 (Merger) | Outside 0.3-1.6 range |
| Warning 11-3 | High relative abundance in R1 (Merger) | > 0.9 |
| Warning 11-4 | High relative abundance in R2 (Merger) | > 0.9 |
| Code | Description | Threshold/Details |
|---|---|---|
| Warning 7-3 | DADA2 merging failure | Merge operation failed |
| Warning 7-4 | R1/R2 not subsequences in DADA2 merged result | Sequence validation failed |
| Warning 11-1 | High ambiguity in merger result | Ambiguous + lowercase sites > 15 |
| Warning 11-7 | Merger merging failure | Merge operation failed |
| Warning 11-8 | R1/R2 not subsequences in merger result | Sequence validation failed |
| Code | Description | Threshold |
|---|---|---|
| Warning 7-2-0 | Low abundance in DADA2 merged result | ≤ 0.9 |
| Warning 9-2 | Low abundance in 10N concatenated result | ≤ 0.9 |
| Warning 11-6-0 | Low abundance in merger result | ≤ 0.9 |
| Code | Description | Details |
|---|---|---|
| Warning 4-1 | Convergence failure in DADA2 error learning (R1) | Error model convergence failed |
| Warning 4-2 | Convergence failure in DADA2 error learning (R2) | Error model convergence failed |
| Warning 5-1 | Insufficient denoised ASV reads in R1 | Best ASV reads ≤ 30 |
| Warning 5-2 | Insufficient denoised ASV reads in R2 | Best ASV reads ≤ 30 |
| Code | Description | Details |
|---|---|---|
| Warning 10-1 | No candidate reference sequence found | BLAST search returned no valid hits |
| Code | Description | Process |
|---|---|---|
| Error 1 | Cutadapt demultiplexing error | Demultiplexing |
| Error 2 | Cutadapt trimming error | Trimming |
| Error 3 | DADA2 filtering error | Filtering |
| Error 4 | DADA2 error learning error | Error learning |
| Error 5 | DADA2 denoising error | Denoising |
| Error 7 | DADA2 merging error | Merging |
| Error 9 | DADA2 10N concatenation error | Concatenation |
| Error 10 | Merger BLAST error | BLAST search |
| Error 11 | Merger merging error | Merging |
- Early stage threshold: Typically 30 reads (configurable via QCValidationThresholds)
- Late stage threshold: Typically 30 reads (configurable via QCValidationThresholds)
- Abundance ratio range: 0.3 - 1.6 (configurable)
- Relative abundance limit: 0.9 (configurable)
- Ambiguity threshold: 15 sites (configurable)
- All thresholds are defined in
src/qc/constants.py(QCValidationThresholds class) - Validation logic is implemented in
src/qc/validator.py - Codes are generated during locus QC processing and stored in the QC database
- Warning codes indicate potential quality issues but do not prevent processing
- Error codes indicate processing failures that may halt pipeline execution
from src.qc.validator import get_validation_codes
# 正常樣本資料
sample_data = {
'cutadapt_demultiplex_r1': 2000,
'cutadapt_demultiplex_r2': 2000,
'dada2_merge_best_asv_number': 50,
'dada2_merge_best_asv_proportion': 0.95,
'ambiguous_sites_number': 2,
'lowercase_sites_number': 3,
'blast_subject_id': 'Pteris_aspericaulis'
}
validation_code = get_validation_codes(sample_data)
print(f"驗證結果: {validation_code}") # 輸出: "PASS"
⚠️ 說明:本章節詳述系統內部的信心度機制(confidence values)與決策追蹤細節。這些是程式碼層級的實作細節,不適合在學術論文或公開報告中引用。論文撰寫時應參考本文件前五章的學術呈現層內容。
推薦引擎在內部使用 0.0 至 1.0 之間的信心度值作為決策路由與結果標記機制:
信心度值對應表(程式碼內部使用):
| 信心度 | 決策情形 | 來源 | 場景說明 |
|---|---|---|---|
| 0.95 | 高豐度採納直接推薦 | 高豐度採納機制 | 序列比例 >= 0.85 時自動推薦 |
| 0.80 | 品質過濾唯一通過(正常) | Rule-based Judge | 低豐度排除後只有一個序列通過 |
| 0.75 | LLM 成功推薦 | LLM Pipeline | LLM 分析後的標準結果 |
| 0.60 | 品質過濾唯一通過(警告) | Rule-based Judge | 含有 Warning 6-1 或絕對豐度偏低 |
| 0.30 | 一般 Fallback | 傳統邏輯 | 多序列無共識時比較最高豐度 |
| 0.10 | 品質過濾全拒絕 | Fallback | 所有序列被過濾掉,回傳最高豐度供人工檢視 |
| 0.00 | 保留未使用 | - | 系統內部未實際使用 |
Step 1:品質過濾階段
Rule-based Judge (evaluate_sample)
├─ 高豐度採納檢查
│ └─ True → confidence=0.95,直接推薦
│
└─ 低豐度排除
├─ 0 個序列通過 → confidence=0.10(全拒絕 Fallback)
├─ 1 個序列通過 → confidence=0.80(或 0.60 含警告)
└─ 2+ 個序列通過 → confidence=1.0(標記 INCONCLUSIVE)
Step 2:仲裁決策階段
INCONCLUSIVE 情形
├─ 前端未勾選規則 → confidence=0.30,傳統 Fallback
│
└─ 前端有勾選規則 + LLM 可用
├─ LLM 成功 → confidence=0.75(或 LLM 提供值)
└─ LLM 失敗 → confidence=0.30,Fallback
信心度值存儲於 recommendation_confidence 欄位:
SELECT
sample_name,
recommendation_source,
recommendation_confidence,
recommendation_reasoning,
recommendation_llm_model
FROM {locus}_qcReport
WHERE recommendation_source IS NOT NULL
ORDER BY recommendation_confidence DESC;在學術報告或論文中引用推薦結果時:
- 不引用具體 confidence 數值 - 這是內部實作細節
- 改用決策分類:
- 「直接推薦」而非「confidence=0.80」
- 「Fallback 序列」而非「confidence=0.30」
- 「LLM 仲裁結果」而非「confidence=0.75」
- 可參考的學術層面資訊:
- 規則 1-6 分類統計
- 品質過濾結果(通過/失敗序列數)
- LLM 仲裁成功率
- 樣本規則分布
信心度策略可能因程式碼更新而改變。參考時應以 src/qc/recommendation_engine.py 中 _process_sample() 與 _process_llm_result() 的實作為準。
- 整體架構:參考
docs/qc.md - 整體統計:參考
docs/overall_qc.md - 資料流向:參考
docs/data_flow.md - 序列萃取:參考
docs/sequence_extraction.md - LLM 整合:參考
docs/llm.md