Skip to content

Latest commit

 

History

History
1473 lines (1078 loc) · 69.1 KB

File metadata and controls

1473 lines (1078 loc) · 69.1 KB

Locus QC 與推薦 (Locus QC)

Locus QC Concept 圖 1: Locus QC 概念圖。系統架構圖,展示 DADA2、Merger、BLAST 數據匯入中心化資料庫,供推薦引擎使用並產出報告。

1. 模組概述

1.1 主要目標

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

1.2 設計理念

核心遵循「資料庫為唯一權威」與「流程一次性重建」:

  • 資料庫優先:所有查詢 / 驗證 / 推薦皆讀取 {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 產生差異,以程式碼為準。

1.3 在統一 QC 流程中的定位

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
Loading

執行特色

  • 承接整體統計:基於整體 QC 提供的基礎資訊進行樣本級分析
  • 中心化管理:所有樣本資料統一管理於 SQLite 資料庫
  • 推薦系統整合:原生整合 6 規則推薦引擎與 LLM 仲裁機制

2. 核心模組架構

2.1 QCDataManager 中心化資料管理器

核心控制器,負責統一管理 {locus}_qcReport.db 資料庫,位於 src/qc/qc_data_manager.py

主要功能

  • collect_all_qc_data():完整的資料收集引擎(主要入口點),執行概要:
    • 步驟 0index_denoise_sequences_to_database() - 將 denoise/ASV 序列的元資料索引進 SQLite(僅儲存元資料與索引,不儲存完整序列),並避免重複索引。
    • 步驟 1-4:樣本資料收集、檔案統計、BLAST 結果整合與豐度分析,最後批次寫入資料庫。

主要已實作的方法(位於 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 欄位完整樣本資料結構(含推薦結果)
  • 增量更新機制,避免重複計算
  • 檔案修改時間追蹤,確保資料時效性

2.2 SequenceRecommendationEngine 序列推薦引擎

統一推薦引擎,整合至 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
Loading

2.2.1 雙層過濾機制:低豐度排除與高豐度採納

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
Loading

雙層過濾機制 - 參數對照表

機制名稱 程式碼參數 型態 預設值 說明
低豐度排除 (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 仲裁

2.2.2 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
Loading

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

2.2.3 完整推薦決策樹

整合高豐度採納、低豐度排除、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
Loading

流程圖說明與實作差異註記

  • 前端勾選分流:核心決策點。是否勾選任何規則,決定是否進入 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_top1merger_top2),引擎再依此透過 _get_dada2_sequence_by_rank / _get_merger_sequence_by_rank 載入對應序列。

主要功能

  1. 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)
  2. _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
  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 或 INCONCLUSIVE
      • metrics:過濾後的序列計數與拒絕理由
      • 內部追蹤值(如信心度)供後續決策分流使用

    Step 2:根據品質過濾結果進行決策分流

    • 品質過濾全拒絕:沒有任何合格序列。

      • 決策:使用品質過濾失敗 fallback,回傳最高豐度序列供人工檢視。
      • 統計rule_{rule}_quality_filter_rejected_count
    • 品質過濾直接決策:品質過濾成功且只有一個合格序列。

      • 決策:直接推薦該序列(無需 LLM)。
      • 統計rule_{rule}_direct_merger_countrule_{rule}_direct_dada2_count
    • 品質過濾多序列INCONCLUSIVE:品質過濾成功但有多個合格序列。

      • 特殊檢查:如果過濾後只剩下兩個序列且完全相同。
        • 條件passed_sequences == 2passed_dada2 == 1passed_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_top1merger_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」。
  4. _save_recommendation_to_db(sample_id, recommendation):即時儲存推薦結果

    • 每處理完一個樣本立即更新資料庫(非批次更新)。
    • 更新欄位:
      • recommendation_source
      • recommendation_sequence
      • recommendation_header
      • recommendation_confidence
      • recommendation_reasoning
      • recommendation_llm_model(若適用)
      • recommendation_timestamp(自動設為 CURRENT_TIMESTAMP)
  5. _extract_recommended_sequences(recommendations):萃取推薦序列並生成 FASTA(.fas)

    • 若推薦含原始 header(多數情況),則直接保留該 header;否則使用 >sample_id|source=...|rule=... 形式。
    • 所有「有實際序列內容」的推薦都會輸出;若無序列則輸出 # 無可用序列 行作為占位。

推薦決策核心邏輯

  • 所有樣本先經 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 過濾部分規則以調整行為

2.2.1 推薦引擎工作流程

優化特色:

  1. 避免重複檢查:先分類再處理,消除 Rule 條件重複檢查
  2. 精確 LLM 控制:只有真正需要的樣本才進行 LLM 分析
  3. 提升整體效率:對大量樣本特別有效,減少不必要的計算
  4. 清晰的分工:每個步驟責任明確,便於除錯與維護

2.2.2 6 規則推薦系統(分類統計用)

_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_top1merger_top2
  • 引擎直接將 source 設為該值,並以對應的 rank 載入序列;不會自動改寫為單純 dada2 / merger
  • 若解析失敗則回退一般 Fallback。

2.2.3 FASTA 檔案生成

系統自動將所有推薦結果彙整為 {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
# 無可用序列

2.2.4 推薦引擎實作架構

系統架構與資料流

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
Loading

核心類別設計

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 分析結果"""

2.3 csvParser.py 資料解析庫

專注於純粹的資料解析功能,提供核心解析函數:

主要功能

  • 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 是否一致

2.4 validator.py 驗證碼生成器

負責品質驗證並生成 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)

2.5 統一處理流程

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
Loading

2.6 資料來源映射表

資料類型 解析函數 來源檔案 輸出格式
樣本對應 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 字串

3. 資料庫架構

3.1 QC 資料庫設計

檔案名稱{locus}_qcReport.db (SQLite3)

主表名稱{locus}_qcReport

3.1.1 核心 QC 欄位集合

欄位來源: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.fas
  • save_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 驗證碼

3.1.2 推薦系統欄位

欄位名稱 資料類型 說明 範例
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

3.1.3 其他表與現況

現行程式碼聚焦於主 QC 表;舊文件提及的 qc_samples, file_metadata, processing_status 等多表分層暫未完全落地或僅部分概念化。若後續加入額外輔助表(例如快取檔案修改時間以支援增量),將在此區更新。現階段不應假設存在增量專用 metadata 表。

3.2 資料庫操作類別

3.2.1 QCDataManager

位於 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 交易支援

3.3 LLM 整合策略

3.3.1 即時 LLM 分析流程

基於 src/llm/analysis_pipeline.py 的 LLMAnalysisPipeline 設計:

統一仲裁流程中的樣本處理

  1. 樣本分類_classify_sample_by_rules() 識別 Rule 1-6
  2. 流程判斷:當前端啟用規則時,所有樣本進入統一仲裁流程
  3. 品質過濾:調用 rule_judge.evaluate_sample() 進行品質評估
  4. 即時分析:若結果為 INCONCLUSIVE 且 LLM 啟用,調用 LLMAnalysisPipeline.run_single_sample_analysis(locus, sample_id)
  5. 結果處理:解析 llm_analysis.final_recommendation.best_result
  6. 資料庫存儲:立即更新推薦結果至 QC 資料庫
  • 步驟 0index_denoise_sequences_to_database() - 將 denoise/ASV 序列的元資料索引進 SQLite(僅儲存元資料與索引,不儲存完整序列),並避免重複索引。
  • 步驟 1-4:樣本資料收集、檔案統計、BLAST 結果整合與豐度分析,最後批次寫入資料庫。
  • 解析失敗status = "completed_with_parsing_error",嘗試使用部分結果
  • LLM 失敗:自動 Fallback(比較最高絕對豐度),信心度 0.30
  • 網路錯誤:重試機制 + 後備邏輯

3.3.2 LLM 使用控制

精確控制策略

  • 統一仲裁流程:當前端啟用規則時,所有樣本進入 rule-as-judge 品質過濾
  • INCONCLUSIVE 處理:只有 rule-as-judge 判定為 INCONCLUSIVE 的樣本才可能進入 LLM
  • 即時處理:每個需要 LLM 的樣本立即分析,避免批次延遲
  • 配置控制PowerBarcoderConfig.llm_analysis_enabled 全域開關
  • 模型選擇PowerBarcoderConfig.llm_model 統一模型設定

3.3.3 關鍵設計決策

信心度策略

系統使用內部信心度機制進行決策路由與結果追蹤。信心度的具體值定義見第 6 節「技術實作層」,此處簡述邏輯:

  • 高豐度採納直接推薦的序列獲得最高信心度
  • 品質過濾唯一通過的序列獲得次高信心度
  • LLM 成功仲裁的序列獲得中等信心度
  • 傳統 Fallback(最高豐度選擇)獲得較低信心度
  • 品質過濾全拒絕的情形獲得最低信心度

人工檢視機制:信心度較低或存在警告的樣本在報告中標記為需人工檢視,並提供詳細的推薦理由。序列匯出時,若無可用序列則輸出佔位符。

序列來源優先級:推薦邏輯已經確保每個樣本只會有一個推薦來源,避免衝突。

觸發時機:推薦引擎在 QC 流程的 run_locus_qc 階段中,執行於所有 LLM 以外的 QC 分析完成之後,執行 generate_csv_report 方法之前。

3.4 序列索引 (Sequence Indexing) 實作細節

為了提升資料存取效能與記憶體使用效率,系統採用序列索引 (Sequence Indexing) 機制,將序列元數據與檔案偏移資訊儲存於資料庫中,而非直接儲存完整序列內容。

3.4.1 asv_sequences 索引表設計

表名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 特殊值:參考集合或非標準來源(例如比對參考)可能使用負數作為標記,不代表錯誤。

3.4.2 Lazy-Load 序列載入機制

當需要完整序列內容時,系統採用延遲載入 (Lazy Loading) 策略:

載入流程

  1. 元數據查詢:從 asv_sequences 表取得 file_pathsequence_start_linesequence_end_line
  2. 檔案讀取:使用 get_sequence_from_index() 函數讀取指定行號範圍的序列內容
  3. 內容解析:提取 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 優化:支援部分檔案讀取,減少磁碟存取量

3.4.3 索引建立與更新策略

索引建立時機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. 批次插入資料庫
        # ...其他步驟

重建邏輯

  1. 檢查現有索引:查詢 asv_sequences 表中是否已有該 locus 的記錄
  2. 清除舊索引:若存在舊記錄,先刪除該 locus 的所有索引資料
  3. 重新掃描:遍歷所有相關 FASTA 檔案,解析序列元數據
  4. 批次插入:將新索引資料批次寫入資料庫

避免重複索引:透過「刪除該 locus 全部舊紀錄 → 重新掃描」策略達成;尚未實作檔案 modified_time 層級的細粒度增量。

流程特點:索引建立是所有後續資料收集與分析的基礎,會在樣本資料處理前完成

3.4.4 常見查詢範例

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)

4. 輸出格式與報告結構

4.1 {locus}_qcReport.csv 匯出結構(動態欄位)

4.1.1 表頭來源

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_coderecommendation_* 欄位(含 recommendation_llm_model)

4.1.2 欄位計算邏輯與資料來源

資料缺失標記規則:任一來源缺失或檔案不存在,欄位值一律設為 "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/r2Merger 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() 實作精確的查詢邏輯:

處理流程

  1. 讀取 BLAST 結果檔案並建立檔案名稱到結果的映射
  2. 根據樣本名稱找到 Highest Abundance ASV 檔案
  3. 使用 Highest Abundance ASV 的檔案名稱查找對應的 BLAST 結果
  4. 統一使用 BLAST 模組的標準計算方法
    • 建立 BlastEntry 物件包含完整 BLAST 資訊
    • 使用 BlastPair.get_identity_score() 計算一致性分數
    • 使用 BlastPair.get_coverage_length() 計算覆蓋長度(含 gap 懲罰)
  5. 回傳該 ASV 的 BLAST 資訊
  6. BLAST subjectIDAvg. BLAST identityAvg. 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:推薦生成時間戳

4.2 資料庫結構

4.2.1 {locus}_qcReport.db 結構

中心化資料庫採用 SQLite 格式,包含以下主要表格:

  • qc_samples:儲存所有樣本的完整 QC 資料(含推薦結果)
  • file_metadata:追蹤檔案變更狀態(支援增量更新)
  • processing_status:記錄處理狀態與錯誤資訊

4.2.2 資料庫操作特色

  • ACID 特性:確保資料一致性
  • 增量更新:只處理變更的檔案
  • 錯誤恢復:完整的事務回滾機制
  • 高效查詢:建立適當索引提升查詢效能

4.3 推薦序列 FASTA 輸出

除了 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

5. 品質驗證規範

5.1 驗證邏輯流程

驗證器執行六大類品質檢查:

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[回傳逗號分隔的代碼字串]
Loading

5.2 六大類驗證規範

5.2.1 低讀長數量檢查 (_check_low_read_numbers)

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)

5.2.2 不平衡豐度檢查 (_check_disproportionate_abundance)

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)

5.2.3 合併問題檢查 (_check_merging_issues)

DADA2 合併 — 合併失敗檢查

  • 警告 7-3:合併失敗
  • 警告 7-4:至少一個方向(r1 或 r2)不是合併結果的子序列

Merger 合併 — 合併失敗檢查

  • 警告 11-1:合併結果具有高模糊度(模糊位點 + 小寫位點 > 15)
  • 警告 11-7:合併失敗
  • 警告 11-8:至少一個方向(r1 或 r2)序列不是合併結果的子序列

5.2.4 結果豐度檢查 (_check_low_abundance_in_results)

DADA2 合併 — 結果豐度檢查

  • 警告 7-2-0:合併結果豐度過低(≤ 0.5)

DADA2 10N 拼接 — 結果豐度檢查

  • 警告 9-2:拼接結果豐度過低(≤ 0.5)

Merger 合併 — 結果豐度檢查

  • 警告 11-6-0:合併結果豐度過低(≤ 0.5)

5.2.5 收斂性與去噪問題檢查 (_check_convergence_denoising_issues)

DADA2 錯誤學習

  • 警告 4-1:R1 錯誤學習收斂失敗
  • 警告 4-2:R2 錯誤學習收斂失敗

DADA2 去噪

  • 警告 5-1:R1 ASV 去噪無法超過閾值(使用者指定閾值 > 30)
  • 警告 5-2:R2 ASV 去噪無法超過閾值

5.2.6 BLAST 比對問題檢查 (_check_blast_alignment_issues)

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 值與意義不同,請勿混淆。

5.3 驗證碼對照表

驗證碼 分類 描述 觸發條件
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.

1. Low Read Numbers

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

2. Disproportionate Abundance

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

3. Merging Issues

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

4. Low Abundance in Results

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

5. Convergence and Denoising Issues

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

6. Reference and BLAST Issues

Code Description Details
Warning 10-1 No candidate reference sequence found BLAST search returned no valid hits

7. Error Codes

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

Threshold Definitions

  • 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)

Implementation Notes

  • 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

5.4 使用範例

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"

6. 技術實作層 - 信心度與決策追蹤機制(Implementation Details)

⚠️ 說明:本章節詳述系統內部的信心度機制(confidence values)與決策追蹤細節。這些是程式碼層級的實作細節,不適合在學術論文或公開報告中引用。論文撰寫時應參考本文件前五章的學術呈現層內容。

6.1 信心度值的程式碼定義

推薦引擎在內部使用 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 保留未使用 - 系統內部未實際使用

6.2 決策路由的信心度使用

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

6.3 資料庫存儲

信心度值存儲於 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;

6.4 後處理建議

在學術報告或論文中引用推薦結果時:

  1. 不引用具體 confidence 數值 - 這是內部實作細節
  2. 改用決策分類
    • 「直接推薦」而非「confidence=0.80」
    • 「Fallback 序列」而非「confidence=0.30」
    • 「LLM 仲裁結果」而非「confidence=0.75」
  3. 可參考的學術層面資訊
    • 規則 1-6 分類統計
    • 品質過濾結果(通過/失敗序列數)
    • LLM 仲裁成功率
    • 樣本規則分布

6.5 文檔與代碼同步

信心度策略可能因程式碼更新而改變。參考時應以 src/qc/recommendation_engine.py_process_sample()_process_llm_result() 的實作為準。


7. 相關文件

  • 整體架構:參考 docs/qc.md
  • 整體統計:參考 docs/overall_qc.md
  • 資料流向:參考 docs/data_flow.md
  • 序列萃取:參考 docs/sequence_extraction.md
  • LLM 整合:參考 docs/llm.md