ms-data-parser 仕様書
MS-DIAL(LC-MS リピドミクス/メタボロミクス解析ソフト)の出力を読み、解析をサーバ側で実行して、LLM に要約だけを返す MCP サーバの完全仕様。各ツールの入力と出力、ツール同士のつながり、統計と行列計算の中身、書き出されるファイルの形までを 1 枚にまとめる。
全体像とアーキテクチャ
MS-DIAL は解析結果を圧縮 MessagePack と独自バイナリで書くため、GUI の外では読めず、チャットに貼るには大きすぎる。このサーバはそれらを読み、標準的な解析(前処理・PCA・差次的解析・同定の裏取り)をサーバ側で回し、LLM には結論が埋もれない大きさの要約・TSV・PNG だけを返す。生の行列は LLM の文脈に載せない。
paper_search(Europe PMC)だけ。生データからの自動統括は MCP プロセスとは別の worker プロセスが進めるので、MCP 接続が切れても run は進む。設計原則
生の行列を返さない
JSON は json_payload() で空白なし、一覧は列名 1 回の TSV、float は丸める。全ツールに structured_output=False(付けないと同じ内容が 2 回送られる)。
座標より PNG
volcano の点列は実測 183,578 字 ≒ 数万トークン、サーバで描いた PNG は約 327 画像トークン。画像トークンは 幅×高さ/750 なので dpi は上げない。
例外でなく封筒
前提状態が無いときは missing_state の JSON 封筒を返し、どのツールを先に呼べばよいかを機械可読で伝える(13 章)。
スロットは形式ごと
session.arf / .arf2 / .pai2 / .eic / .dataset / .library は互いに触らない。ピーク検証の往復で ARF の前処理行列が消えない。
曖昧なら止める
複数候補のメソッドファイル・mzTab・ライブラリ・PCA 結果は、更新日時や辞書順で黙って選ばず、*_AMBIGUOUS などで止めて選ばせる。
確度を名乗らせない
MS/MS の「フラグ」と「実スペクトル」、MS1 注釈と MS/MS 証拠、gap-fill と実検出を全経路で区別し、弱い根拠を強い根拠に数えない。
パッケージ構成と依存の向き
lipidmix.core.mcp_core から形式別 tools や lipidmix.tools.* を import すると循環になる。可変状態(DATA_DIR KNOWLEDGE_DIR ANALYSES_DIR と session)の正準は core 側で、server.<name> はスナップショットにすぎない。アラインメントのキュレーション(lipidmix/curation/:証拠収集・機械判別・フラグ記録・ビューア HTML・MS-DIAL への書き戻し)は図では省いたが、analysis/ と同じ層にあり、公開層は lipidmix/tools/curation_tools.py。入力データと粒度
同じ LC-MS データが、ファイルごとに別の粒度で書かれている。「1 行」が何を指すかを取り違えると、検出率も同定も壊れた数字になる。
.arf の 1 行は「1 スポット × 1 試料」、.arf2 の 1 行は「全試料を統合した 1 スポット」。ハッチのセルは gap-fill(未検出を補間した値)で、検出率や存在判定では実測と別に扱う。ID はすべて 0 始まり。| 形式 | 中身 | 1 行 / 1 要素の粒度 | エンコード | 読むツール | スロット |
|---|---|---|---|---|---|
.arf*_PeakProperties.arf | アライン後の試料別ピーク(高さ・面積・m/z・RT・S/N・gap-fill・MS/MS 取得) | 1 スポット × 1 試料 | MessagePack ストリーム+LZ4 ブロック(AlignmentChromPeakFeature) | arf_parser ほか ARF 系 | session.arf |
.arf2 | スポット代表カタログ(名前・式・Ontology・SMILES・InChIKey・アダクト・強度統計・Fill%)。試料別強度は無い | 1 スポット(22 列) | MessagePack [header, compressed]+LZ4(AlignmentSpotProperty) | arf2_parser・arf2_annotate_identities | session.arf2 |
.pai2 | 1 測定ファイルの検出ピーク(アライン前) | 1 ファイル内の 1 ピーク | MessagePack+LZ4(ChromatogramPeakFeature) | pai2_parser・verify_peak_annotation | session.pai2 |
.dcl | デコンボリューション済み MS/MS(MSDecResult) | 1 プリカーサ | 独自リトルエンディアン・バイナリ(MessagePack ではない) | dcl_parser・dcl_find_msms・自動充填 | なし |
.EIC.aef | 抽出イオンクロマトグラム | 1 スポット × 1 試料の点列 | 独自バイナリ(magic CSS1) | eic_* | session.eic |
| mzTab-M 2.0 | Console が産む標準交換形式。MTD / SML / SMF / SME の 4 表 | SMF 1 行 = 1 特徴 | タブ区切りテキスト | dataset_load | session.dataset |
| サイドカー | *_tags.xml(タグ)、.mddata(Class ID・注入順。ZIP)、.mdproject(.mddata へのポインタ) | — | XML / ZIP | ARF 系が自動で読む | — |
2.1 バイナリの解き方
MessagePack の Key 番号の正解表は docs/schema/*.md(MS-DIAL の C# クラスの [Key(N)] から上流 commit 45a531c 時点で抽出)。インデックス定数を変える前に必ずここを見る。推測で直さない。
LZ4 包みの MessagePack ストリーム
- トップレベルの msgpack オブジェクト(ExtType か
[header, ExtType|bytes])を順に読む。 - ブロック先頭の msgpack int が展開後サイズ。
lz4.block.decompress(rest, size)で中身を得る。 - 中身はスポット「群」(行のリスト)。群の通し番号が
MasterAlignmentID。 - unpacker は
unicode_errors="ignore"(POS ファイルに壊れた UTF-8 がある)・strict_map_key=False・1 GiB バッファ。
行の Key: 0 FileID · 1 FileName · 2 MasterPeakID(負 = gap-fill)· 3 PeakID · 9 MS2RawSpectrumID · 10 MS2RawSpectrumID2CE(非空 = MS/MS 取得)· 15 ChromXsTop(RT)· 18 PeakHeightTop · 20 AreaAboveZero · 21 AreaAboveBaseline · 22 Mass · 37 PeakShape [noise, S/N]
固定長ブロックの独自形式
- ヘッダ 11 B:
"DC"+ int32 版 + bool 注釈 + int32 件数。続いて件数 × int64 のシーク位置。 - レコードごと: Scan 60 B(+8 ScanID、+12 RawSpectrumID、+16 PrecursorMz f64、+24 IonMode i32、+28 RT f64)→ Quant 5×f64 → Scoring 5×f32(amp・purity・quality・S/N・noise)→ Counts 3×i32 → ピーク 20 B ずつ(mass f64・intensity f64・quality i32)。
dcl_indexが同名.pai2のピーク順に対応する設計。
CSS1 形式
magic CSS1 → offset 10 へ → int32 スポット数 → int64 ポインタ列。スポットごとに 4×f32(rt・ri・mass・drift)・i8 main_type・i32 試料数、試料ごとに i32 file_id・i32 点数・f32 top/left/right、続いて (f32 x, f32 強度) × 点数。描画系は必要なスポットだけをポインタで直接読む。
単発 unpackb + LZ4
.arf2: 0 MasterAlignmentID · 4 TimesCenter→RT · 5 MassCenter · 11 IonMode · 12 Name · 13 Formula · 14 Ontology · 15 SMILES · 16 InChIKey · 31 HeightAverage · 49 FillParcentage(原文ママ)· 54 AdductType
.pai2: 3/4/5 time left/top/right · 9 area · 11 MasterPeakID→id · 18 MS2RawSpectrumID · 19 CE map · 25 Name · 29 InChIKey · 40 PeakShape[1]→S/N · 43 Mass
has_msms = bool(ce_map) or ms2_id ≥ 0。取得参照があるだけで、スペクトル本体は .dcl にある。
2.2 mzTab-M の 2 つの同定の出所
ShouldWriteSmeLine が除外)ので、Text DB 運用では SME 0 行・SML のみが正常。identified_by の sme(MS/MS 証拠あり)と sml_only(MS1 注釈のみ)を足して「同定件数」にしない。abundance_assay[N] は非ゼロでも実測か補間かを区別しない。実データ(60 試料 × 714 特徴)ではセルの 70.0% が gap-fill で、非ゼロを検出と数えると検出率を 3 倍以上に過大評価する。隣接 .arf が同一アライメントだと数値で確かめられたときだけ(スポット数一致と全特徴の m/z 差 0.01 Da 以内)ds.detected_mask を取り込む。derive_inchikey は database_identifier(InChIKey の正規表現に一致するとき)→ InChI → SMILES の順に RDKit で導出する。MS-DIAL は SML の inchi を常に null で書き、database_identifier は <db>:<name> 形式なので、SML から InChIKey に届くのは SMILES 経由だけ。2.3 読み間違えやすい値
| 値 | 見た目 | 実際の意味 |
|---|---|---|
Name | 同定名 | 空文字・Unknown・no MS2:・low score: を含みうる。存在するだけで確定同定ではない。| は複数候補の連結で左が代表とは限らない |
Ontology | 化合物名 | 脂質クラス(headgroup 分類)。空文字と文字列 Unknown は別扱い |
ARF HeightAverage | 全試料平均 | 現実装ではグループ先頭試料の値。統合統計は ARF2 側を使う |
ARF 要約 named_compounds | 注釈済み件数 | 空文字も数える。注釈率には使わない |
PAI2 has_msms | MS/MS あり | 取得参照があるだけ。実スペクトルは .dcl |
DCL n_msms_peaks | 返した本数 | 間引き前の元本数。top_n_peaks 適用後の配列長と違いうる |
EIC peak_top | ピーク強度 | 頂点の横軸座標(RT)。強度は max_intensity |
EIC total_samples | 試料数 | 全スポットのエントリ総数。ユニーク数は len(unique_file_ids) |
ARF2 FillPercentage | 百分率 | 0..1 の比率 |
| mzTab-M RT | 分 | ファイル上は秒。DatasetState は分に揃える |
2.4 脂質名の文法(assay_kind=lipid のときだけ)
| 表記 | 意味 | 例 |
|---|---|---|
| クラストークン | 先頭の脂質クラス = Ontology | PC TG Cer_NS |
C:D | 全アシル鎖合計の炭素数:二重結合数(species レベル、鎖は未確定) | PC 34:1 |
C:D/C:D と _ | 鎖を確定した molecular species。/ は sn 位置まで、_ は sn 順不明 | PC 16:0/18:1 · 18:1_16:0 |
;O ;O2 | 追加酸素・水酸基の数 | Cer 18:1;O2/16:0 |
O- / P- | アルキルエーテル / プラズマローゲン。pygoslin は species レベルで PC P-34:0 を PC O-34:1 に同一化する | PC O-34:1 |
一般代謝物(assay_kind=metabolite)ではこの文法は成り立たず、同定の実体は候補集合(アダクト・異性体・候補順位)になる。種別が未確定のあいだはどちらの規則も当てない。
入口と 4 つの経路
利用者が手元に何を持っているかで入口が決まる。サーバ共通指示(MCP_INSTRUCTIONS の ENTRY POINT / GATEWAY)はこの判定を LLM に教え、最初に呼ぶツールを 1 つに絞らせる。
load_dataset / arf_parser などが返す「意味論ダイジェスト」(出力の読み方の必須注意)が 1 回だけ前置される。アッセイ種別(assay_kind)が確定したときにもう 1 回だけ届く。経路の全体地図
4 本の経路は別々のセッションスロットを使うので、並行して進めても互いの状態を壊さない。矢印は「前段が書いた状態を後段が前提として読む」を表す。実線は必須の前提、破線は任意。各箱の 2 行目は、そのツールが書く状態または出力。
dataset_load(pipeline_path=…) で mzTab-M 経路の対話セッションへそのまま引き継げる(同じ run の DatasetState・試料対応表・binding・解析行列をまとめて載せる)。save_pca_figure / save_volcano_figure は ARF と mzTab-M の両方を入力にでき、両方に有効な結果があると AMBIGUOUS_RESULT_SOURCE で止まる。| 経路 | 入力 | 正準状態 | 行の ID 空間 | 向いている場面 |
|---|---|---|---|---|
| ARF | MS-DIAL GUI の .arf(+兄弟 .arf2、.mddata、*_tags.xml) | session.arf | MasterAlignmentID | GUI で解析済みのデータを探索的に見る。タグ・Class ID・因子トークンで柔軟に絞る |
| mzTab-M | mzTab-M 2.0(Console 出力)。隣接 .arf があれば検出状態も | session.dataset(DatasetState) | SMF_ID | 来歴を検証したいとき。実験情報シートで群・順序を訂正したいとき。v2 統計 |
| pipeline | 生データフォルダ 1 つ(+任意で analysis-request.json / sample-manifest.tsv) | pipeline-run.json(別プロセス) | SMF_ID | 生データから品質レポートまで無人で。中断・訂正・再開を冪等に |
| 同定・確認 | .pai2・.dcl・.EIC.aef・.arf2・参照ライブラリ | session.pai2 / .eic / .library | ピーク ID · spot_id | 「この注釈は本物か」を MS/MS・精密質量・クロマトグラムで確かめる |
| キュレーション | アラインメントの .arf2(+兄弟 .arf・.dcl・.EIC.aef・*_tags.xml)と、アラインメントに使った参照ライブラリ | <アラインメントのフォルダ>/curation/flags.jsonl(正本)+ session.curation | MasterAlignmentID | 注釈付きスポットを一覧で確かめ、「間違い」「疑わしい」を記録してエクスポートと MS-DIAL に返す(独立した枝・いつでも) |
DatasetState は分に揃える)。同じ「spot_id」列でも MasterAlignmentID と SMF_ID を混ぜて読まない。mzTab-M 経路のエクスポートはメタ行 # id_space = mztab_smf_id で ID 空間を宣言する。3.1 独立した枝:アラインメントのキュレーション
MS-DIAL の GUI で 1 件ずつ見ていた注釈の確認(EIC・対向プロット・Δm/z・ΔRT・RT–m/z の線形性)を、一覧と機械判別で短くする枝。どの経路とも状態を共有せず、いつでも入れる。前提は 2 本で、どちらも missing_state で止まる:.arf2 が解決できること(load_dataset か arf2_parser)と、参照ライブラリが読み込み済みであること(library_load。アラインメントと同じフォルダの *_Loaded.msp2.dbs を推奨)。
curation_review— 一覧と機械判別注釈付きスポット(既定は全部、
ontologyでクラス、name_containsで名前)の証拠を集めて判定し(8.4 節)、ビューア HTML を書く。LLM に返すのはsuspect以上とフラグ済みの TSV・件数・クラス別の傾向要約・html_pathだけで、EIC 系列とスペクトルは返さない。ユーザーがビューアで確かめる
html_pathをブラウザで開く。likely_wrongは赤の破線枠で「間違い」が初期選択、メモ欄には判定根拠が入っている。クラスの選択肢の「<クラス> › 自動判別: 間違い」で絞れる。直したら「送信用テキストをコピー」してチャットに貼る。curation_submit— 記録と MS-DIAL への反映貼られた文をそのまま渡す。
flags.jsonlに追記し(正本)、アラインメントの_tags.xmlの Misannotation を付け外しする(wrong→ 付ける、取消 → 外す、suspect→ 触らない)。エクスポートと表に効く
arf_export_differential/dataset_export_differentialは既定でwrongのスポットを同定なしとして外し、メタ行# curation = …で宣言する(10.1 節)。arf2_annotate_identitiesはcuration_flag列を持つ。curation_flagsで有効なフラグを一覧できる。
wrong)と「疑わしい」(suspect)だけ。無印は「間違っていない」の意で、何も記録しない。フラグは .arf2 の sha256 と MasterAlignmentID の組で持つので、MS-DIAL を再実行してアラインメントが変わると古いフラグは当たらなくなる(件数は warnings で知らせる)。セッション状態と前提連鎖
サーバは 1 プロセスに 1 つの session = AnalysisSession() を持つ。ツールは前段が書いた状態を読み、無ければ例外ではなく missing_state 封筒で「先にどれを呼ぶか」を返す。クライアントはそれを読んでリプレイする。
pai2_parser が ARF の前処理行列を無言で破棄した過去のバグの再発防止)。ArfState.load_data() はパスかタグディレクトリが変わったときだけ再パースし、切り替え時は派生状態を reset_analysis() で消す。図に無い session.curation は直近の review_id とレビューの保存先だけを持つ(判定結果とフラグの正本はディスク)。4.1 前提状態の連鎖表
「このツールを呼ぶには何が要るか」。前提が無いときに返る封筒の required_tools は OR の代替候補で、クライアントは候補のうち本セッションで成功した直近の呼び出しを記録済みの引数のまま再実行する(LLM に再実行させると前処理の引数が変わりうる)。
| ツール | 必要な状態 | required_tools(生成元) |
|---|---|---|
arf_list_classes arf_list_tags arf_list_sample_roles arf_exclude arf_preprocess | ARF データ | arf_parser / load_dataset |
arf_pca_preprocessed arf_differential | 前処理済み行列 preprocessed_matrix | arf_preprocess |
arf_plot_volcano | 2 群の差次的結果 | arf_differential |
arf_export_differential | 2 群の差次的結果 + 兄弟 .arf2 | arf_differential |
pai2_inspect_peak verify_peak_annotation | pai2_dataset | pai2_parser |
library_match_feature | session.library.store | library_load |
library_plot_mirror | last_match(候補 1 件以上) | library_match_feature |
dataset_status dataset_preprocess dataset_set_sample_metadata dataset_build_matrix | session.dataset | dataset_load |
dataset_pca dataset_differential | 前処理済み DatasetState | dataset_preprocess |
dataset_export_differential | 現在の前処理から出た差次的結果 | dataset_differential |
dataset_statistic | 登録済みの解析行列 | dataset_build_matrix / dataset_load(pipeline_path) |
dataset_build_matrix(base="internal_standard_ratio") | feature_bindings | dataset_load(pipeline_path)(v2 run) |
save_pca_figure | PCA 結果(ARF か mzTab-M) | arf_parser / arf_pca_preprocessed / load_dataset / dataset_pca |
save_volcano_figure | 差次的結果 | arf_differential / dataset_differential |
save_eic_figure | EIC payload | eic_plot_chromatograms / eic_plot_compounds |
console_run | 計画済みジョブ | console_plan |
curation_review | .arf2(arf2_file)+ session.library.store(library) | load_dataset / arf2_parser、library_load |
curation_flags | .arf2(arf2_file) | load_dataset / arf2_parser |
EIC の検索系(eic_parser と eic_search_*・eic_rank_by_max_intensity)は EicState.load_data() を通るので、どれから呼んでも未ロードなら読み込まれ、missing_state にはならない。
4.2 ツールの annotations
全ツールが MCP 標準の ToolAnnotations を宣言する。readOnlyHint=true は「サーバの外(ファイル・ネットワーク)に副作用が無い」を意味し、サーバ自身の解析セッション状態の更新は副作用に数えない(依存関係は封筒で伝えるため二重に表現しない)。openWorldHint=true は paper_search だけ。同じ引数での再実行が安全かは readOnlyHint か idempotentHint で判断できる。curation_submit は destructiveHint=true:記録は追記だが、MS-DIAL の _tags.xml を書き換え、取消では Misannotation を外すため(書く前に控えを取る)。
全 71 ツール リファレンス
各カードは「シグネチャ・何をするか・入力・出力・前提・状態変更・注意」を同じ順で持つ。見出しをクリックすると開く。引数名と既定値は実登録のシグネチャから取った。
3データ探索・入口
どこから入っても最初に触れる 3 ツール。
list_data_filesフォルダ内のファイルを拡張子別に一覧する。
- シグネチャ
- list_data_files(extension=None, directory=None, all_files=False)
- 入力
directory(省略時DATA_DIR)、extension(例.arf2)、all_files(生データも含める)- 出力
- 拡張子ごとの絶対パス一覧。既定は解析できる拡張子だけ(.arf .arf2 .pai2 .dcl .EIC.aef .mddata .mdproject)。
all_files=Trueで abf/ibf/cdf/mzml/wiff/raw/d/wiff2/qgd/lcd/lrp/imzml も。.dと Waters の.rawはフォルダ=1 検体なので末尾に/ - 前提
- なし
- 状態変更
- なし
- 注意
- 実データでは 495 ファイル中 7 割以上が生データだったため既定で隠す。フォルダ形式の判定は
console/job_manager.is_raw_input()(MS-DIAL のisVendorDirectoryと同じ規則)を借りる。見つからなければ空リスト。
load_datasetMS-DIAL 出力フォルダの入口。arf2 概観 → arf PCA を一括実行する。
- シグネチャ
- load_dataset(directory=None)
- 入力
directory(省略時LIPIDMIX_DATA_DIR)- 出力
- 意味論ダイジェスト、バッチ選択の説明(複数バッチなら最新
AlignmentResult_<timestamp>を選んだ旨)、arf2_parserの要約、arf_parserの PCA 要約。更新があれば冒頭行に通知 - 前提
- なし
- 状態変更
mcp_core.DATA_DIRを差し替え、session.arf2とsession.arfを埋める- 注意
PeakProperties.arfをDriftSpots.arfより優先して自動選択する。複数バッチの告知は解析対象の.arf/.arf2のタイムスタンプだけで判断する。
sample_search因子トークン(ILG_6h 等)で試料を探し、file_id と .pai2/.dcl の実パスを返す。
- シグネチャ
- sample_search(specs=None, directory=None, extensions=None, include_roles=None)
- 入力
specs(トークンのリスト。省略で語彙一覧)、extensions、include_roles(既定は全 role)- 出力
- 一致した試料の
file_id・名前・role・Class ID と兄弟ファイルのパス。specs省略時は使えるトークン語彙 - 前提
- なし
- 状態変更
- なし
- 注意
- ARF ロード前でも動く。Class ID に無い因子(時点・複製)もサンプル名から解決する。
2ARF2(スポット代表カタログ)
サンプル別強度を持たない軽量なメタ層。PCA はできない。
arf2_parser.arf2 を読み、データセット全体のメタデータ概観を要約する。
- シグネチャ
- arf2_parser(file_path=None)
- 入力
file_path(省略時は最新バッチ)- 出力
- 総スポット数、注釈数と注釈率、RT/m/z 範囲、強度中央値、イオンモード内訳、S/N 中央値、Ontology 上位 10(自然言語テキスト)
- 前提
- なし
- 状態変更
session.arf2にカタログ(22 列)を保持- 注意
annotated_countはNameが空・null・Unknown以外の件数で、確度は考慮しない。FillPercentageは 0..1 の比率。
arf2_annotate_identitiesスポット注釈を GOSLIN 正規化・RefMet/LIPID MAPS ID・MSI レベルで一括標準化する(オフライン)。
- シグネチャ
- arf2_annotate_identities(file_path=None, max_rows=50)
- 入力
file_path、max_rows- 出力
- TSV 表(列名 1 回。末尾列
curation_flag=wrong/suspect/ 空)。ヘッダ行に総スポット数と未表示件数。ファイル先頭からmax_rows件で、強度順でも MSI 順でもない。フラグ記録が読めなければ一覧は返し、curation_flagを空にして注記する - 前提
- なし
- 状態変更
- なし
- 注意
- ARF2 には MS/MS 取得フラグも精密質量誤差も無いので
has_msms=False・バンド UNKNOWN の保守評価(クラス上限)。参照表はモジュールで 1 回だけ読み、.arf2はload_catalog()(パス+mtime+サイズでキャッシュ)経由。
10ARF(サンプル別強度・PCA・差次的解析)
session.arf を介して状態を受け渡す主経路。生行列 PCA と前処理後 PCA は独立した経路。
arf_parser.arf を読み PCA を実行する。フィルタ条件を変えた再 PCA も本ツールの再呼び出しで行う(再パースは走らない)。
- シグネチャ
- arf_parser(file_path=None, props=None, components=None, top_features=10, log_transform=False, min_detection_rate=0.0, min_intensity=0.0, annotation_keyword=None, tag_labels=None, tag_mode='any', tag_scope='sample_peak', tag_directory=None, missing_sample_policy='error', class_ids=None, class_missing_sample_policy='error', group_levels=None, group_factors=None, include_roles=None, spot_ids=None, ontologies=None)
- 入力
- 行列:
props(既定 height)、min_detection_rate、min_intensity(スポット平均強度の下限)。選択:annotation_keyword(部分一致。ARF2 名を優先)、spot_ids、ontologies(完全一致)— 各 AND。タグ:tag_labels・tag_mode(any/all/none/not_all)・tag_scope(sample_peak/alignment_spot)。試料:class_ids(OR、大小無視)、include_roles(既定で QC/blank を外す)。色分け:group_levels/group_factors - 出力
- Markdown 1 件: 総スポット数、フィルタ・手動除外の注記、Class ID 分布、タグ件数、PCA 行列形状、PC1/PC2 寄与率、ローディング上位、スコアプロット用ブロック(群別件数・描画指示・
points[]の json 点列) - 前提
- なし
- 状態変更
session.arfに features / filtered_features / tag_index / class_index / last_pca / last_pca_plot。選択を変えると古い前処理行列・差次結果を無効化- 注意
- 部分集合で TIC 正規化すれば分母が、BH 補正すれば検定数が変わる。全体の FDR を保ったまま候補を見るなら全体で解析した結果を参照する。選択後に PCA 次元が足りなくても選択は保存し、PCA をスキップした理由を返す。
arf_list_classes現在の ARF データセットで使える Class ID と因子トークンを一覧する。前提
- シグネチャ
- arf_list_classes()
- 入力
- なし
- 出力
.mddataのパス、Class ID 別サンプル数、位置別の因子語彙(JSON)- 前提
arf_parserかload_dataset- 状態変更
- なし
- 注意
- 語彙は常にデータセット全体(
session.arf.features)から作る。直前の絞り込みを引き継ぐと痩せた語彙を返してしまうため。
arf_list_tagsロード済み ARF の MS-DIAL タグを一覧する。前提
- シグネチャ
- arf_list_tags()
- 入力
- なし
- 出力
- タグ定義、サンプルファイル対応数、タグ付与数(JSON)
- 前提
arf_parserかload_dataset- 状態変更
- なし
arf_list_sample_roles試料を sample / qc / blank に分類して前処理前に確認する。前提
- シグネチャ
- arf_list_sample_roles()
- 入力
- なし
- 出力
- TSV(列: sample / role / group / batch / run_order / excluded)。全行同値の
batch_sourceはヘッダ行へ - 前提
arf_parserかload_dataset- 状態変更
- なし
- 注意
- 前処理は適用しない。
arf_excludePCA の外れ試料や特定スポットを名前/ID で手動除外・再包含する(可逆・非破壊)。前提
- シグネチャ
- arf_exclude(exclude_samples=None, exclude_spots=None, mode='add')
- 入力
exclude_samples(file_name 完全一致)、exclude_spots(MasterAlignmentID)、mode= add / remove / clear / list- 出力
- JSON: status・mode・excluded_samples・excluded_spots・samples_before/after・spots_before/after・unmatched_samples/spots・caveats
- 前提
arf_parserかload_dataset- 状態変更
session.arf.excluded_samples/excluded_spots。filtered_featuresは変えない- 注意
- 存在しない指定は unmatched として警告し、一致分だけ反映(タイプミスに寛容)。新ファイルのロードでリセット。行列を組む直前に
prune_spots()が適用される。
arf_preprocessロード済み ARF 行列に前処理レシピを適用する(6 章)。前提
- シグネチャ
- arf_preprocess(normalize='none', blank_min_fold=None, drift_correct=False, max_qc_rsd=None, impute='half_min', props=None)
- 入力
normalize(tic/median/pqn/none)、blank_min_fold、drift_correct、max_qc_rsd(比率)、impute(half_min/knn/column_mean/none)、props- 出力
- JSON report: recipe_applied / skipped、steps、caveats、features_before/after、features_removed_total、unscaled_samples、qc_interspersion、excluded_from_matrix
- 前提
arf_parserかload_dataset- 状態変更
session.arf.feature_matrix/ pp_sample_names / pp_feature_names / sample_meta / preprocessing_recipe
arf_pca_preprocessed前処理済み行列で PCA を実行する。前提
- シグネチャ
- arf_pca_preprocessed(components=None, top_features=10, log_transform=False, group_levels=None, group_factors=None)
- 入力
components、top_features、log_transform、色分け軸- 出力
arf_parserと同じ構造のテキスト+前処理レシピ。QC 点を含む(群ラベルは QC の Class ID かqc)- 前提
arf_preprocess- 状態変更
session.arf.last_pca- 注意
- 色分けや log 変換だけを変えて再実行しても前処理はやり直さない。
arf_differential前処理後行列で 2 群比較(Welch t+log2FC、BH)を行う。前提
- シグネチャ
- arf_differential(group_a=None, group_b=None, q_threshold=0.05, log2fc_threshold=1.0, log_transform=True)
- 入力
group_a(基準)/group_b(比較): 因子トークンでプール指定可、閾値、log_transform- 出力
- summary(n_tested / n_significant / n_up / n_down / top 15)、resolved_samples、n_a / n_b、resolved_class_ids、caveats、volcano_note。全量 volcano は同梱しない
- 前提
arf_preprocess- 状態変更
session.arf.last_differential- 注意
- QC/blank は常に除外(オーバーライド不可)。上位ヒットの名前は ARF が Unknown のとき同一アラインメントの兄弟
.arf2から補う(name_source)。多群は非公開。
arf_export_differential直近の差次的結果を InChIKey 付きの契約 TSV 1 ファイルへ書き出す。前提書込
- シグネチャ
- arf_export_differential(output_path, apply_curation=True)
- 入力
output_path、apply_curation(既定 true。キュレーションでwrongのスポットを同定なしとして外す)- 出力
- メタ行+15 列 TSV(10 章)。有意行だけでなく InChIKey が付いた全行
- 前提
arf_differential(2 群)+ 同一語幹の兄弟.arf2- 状態変更
- なし(ファイルを上書き)
- 注意
.arf2のMasterAlignmentIDで InChIKey・Ontology・m/z・RT を結合。InChIKey 無しの行は本文から外し件数だけ残す。0 行ならエラー。契約版・符号が現行と違う結果は再実行を要求。フラグがあればメタ行# curation = …を足し、payload のcurationに{state, wrong_excluded, suspect, orphaned}。flags.jsonlに読めない行があれば書き出さずに止まる(wrongを黙って落とさない)。
arf_plot_volcano直近の 2 群比較を volcano 図で返す。前提
- シグネチャ
- arf_plot_volcano(max_points=800, title=None, output=None)
- 入力
output(image 既定 / payload)、max_points(payload の ns 間引き上限)、title- 出力
- image: PNG +
up= down= ns=の件数キャプション(全特徴を描画)。payload:lipidmix.volcano.v1(up/down 全件、ns は等間隔で間引き、selectionに件数) - 前提
arf_differential- 状態変更
- なし
- 注意
- ファイルは書かない。保存は
save_volcano_figure。
6EIC(.EIC.aef)
クロマトグラムの検索と描画。peak_top は座標であって強度ではない。
eic_parser.EIC.aef を読み要約を返す。
- シグネチャ
- eic_parser(file_path=None)
- 入力
file_path- 出力
- JSON: total_spots、rt_range、mz_range、total_samples(エントリ総数。ユニーク数ではない)、total_peaks(全点数)、unique_file_ids
- 前提
- なし
- 状態変更
session.eic
eic_search_by_mz_rangem/z 範囲でスポットを探す。
- シグネチャ
- eic_search_by_mz_range(file_path=None, min_mz=0.0, max_mz=1500, max_results=20)
- 入力
- m/z 範囲(上限既定 1500。TG/DGDG/CL を切り落とさない)、
max_results - 出力
spot_id/ rt / mz / num_samples の表(境界値を含む)- 前提
- なし
- 状態変更
- 未ロードなら
session.eicを読む
eic_search_by_rt_rangeRT 範囲でスポットを探す。
- シグネチャ
- eic_search_by_rt_range(file_path=None, min_rt=0.0, max_rt=20.0, max_results=20)
- 入力
- RT 範囲(分)
- 出力
- 同上
- 前提
- なし
- 状態変更
- 未ロードなら
session.eicを読む
eic_rank_by_max_intensity各試料のクロマトグラム最大強度の最大値で降順に並べる。
- シグネチャ
- eic_rank_by_max_intensity(file_path=None, top_n=20)
- 入力
top_n- 出力
- spot_id / rt / mz / num_samples / max_intensity
- 前提
- なし
- 状態変更
- 未ロードなら
session.eicを読む - 注意
- 旧ツールは
peak_top(RT 座標)で並べており、実質「遅い RT の一覧」だったので置き換えた。
eic_plot_chromatograms1 スポットの EIC 系列をクライアント中立の構造化プロット情報で返す。
- シグネチャ
- eic_plot_chromatograms(spot_id, file_path=None, file_ids=None, normalize='none', title=None)
- 入力
spot_id、file_ids(最大 12。省略時は試料 12 以下なら全部)、normalize(none / per_trace_max)- 出力
lipidmix.eic.v1: axes、spot rt/mz、series[].x/y(4 桁丸め)・file_id・label・peak_left/top/right- 前提
- なし
- 状態変更
- payload をセッションに記録(
save_eic_figureの入力) - 注意
- 画像を作らない。1 スポット分だけを CSS1 から直接読む。
eic_plot_compounds脂質名/オントロジーで選んだ複数物質の EIC を 1 試料分だけ重ねる。
- シグネチャ
- eic_plot_compounds(file_id, names=None, ontologies=None, file_path=None, arf2_path=None, normalize='none', top_n=8, title=None, output=None)
- 入力
file_id(必須・1 試料)、names(部分一致)とontologies(完全一致)の和集合、top_n(既定 8)、output- 出力
- image: PNG + 描いた物質と落とした物質の 1 行キャプション。payload:
lipidmix.eic.multi.v1(sample、series[] を RT 昇順、selection.candidates / candidates_evaluated / plotted / dropped[]) - 前提
- なし
- 状態変更
- payload をセッションに記録
- 注意
- ARF2 の同定を EIC スポットの rt/mz(±0.02 min / ±0.01 Da)で検証し、外れを
droppedに理由付きで残す(rt_mismatch / mz_mismatch / spot_out_of_range / file_id_absent / below_top_n)。一致 300 件超は HeightAverage 上位 300 に予備選抜。図に無い=試料に無い、ではない。
3PAI2 とアノテーション検証
1 ファイル = 1 試料のアライン前ピーク。MS/MS の実体は .dcl にある。
pai2_parser.pai2 を読み、ピーク在庫要約を返す。兄弟 .dcl を探して実フラグメントを充填する。
- シグネチャ
- pai2_parser(file_path, filter_threshold=None)
- 入力
file_path(必須)、filter_threshold(強度下限)- 出力
- total_peaks、annotated_peaks(Unknown・no MS2:・low score: を除く)、annotated_fraction、ion_mode_counts、mz/rt_range、height_summary、sn_summary、top_by_height(10)、msms_attachment(attached / dcl_file / caveat)
- 前提
- なし
- 状態変更
session.pai2(features / filtered_features。MS/MS 充填済み)- 注意
- PCA はしない(単一試料)。precursor m/z が 0.01 超ずれたら付与しない。
.dclが無くても caveat を付けて続行(未確認であって不在ではない)。
pai2_inspect_peak特定ピークの強度・S/N・MS/MS 相当フィールドの有無を返す。前提
- シグネチャ
- pai2_inspect_peak(peak_id=None, peak_name=None)
- 入力
peak_idかpeak_name(部分一致、複数可)- 出力
matches[]: id / name / m/z / rt / height / area / signal_to_noise / has_msms_like_fields / formula / adduct / comment- 前提
pai2_parser- 状態変更
- なし
- 注意
has_msms_like_fieldsはキー名の有無だけで、実スペクトルが非空かは見ない。
verify_peak_annotation1 ピークの注釈妥当性を検証するドシエを返す。前提
- シグネチャ
- verify_peak_annotation(peak_id=None, peak_name=None)
- 入力
peak_idかpeak_name- 出力
- ドシエ: analytical_checks(精密質量誤差 ppm・アダクト整合・
msms.band= PASS / FLAG_ONLY / ABSENT、PASS かつライブラリ読込済みなら spectral_match)、identity_normalization(goslin / reference / msi / class_token)、エーテル caveat、蓄積ノートの語彙ヒット、llm_decision.deterministic_summary - 前提
pai2_parser- 状態変更
- なし
- 注意
- MSI Level 2 を主張する前に
bandを見る。PASS = 実スペクトルを見た、FLAG_ONLY = フラグだけ。Level 1 は決して主張しない(8 章)。
2DCL(デコンボリューション済み MS/MS)
MessagePack ではない独自バイナリ。dcl_index が同名 .pai2 のピーク順に対応する。
dcl_parser.dcl を読み在庫要約と先頭数件の主要フラグメントを返す。
- シグネチャ
- dcl_parser(file_path=None, top_n_peaks=None, preview=5)
- 入力
file_path(特定試料なら明示)、top_n_peaks(既定 10、0 で全件)、preview- 出力
- summary(total_results / with_msms / msms_rate_pct / 中央値・最大フラグメント数 / precursor・RT 範囲)+ preview[](dcl_index / precursor_mz / rt / n_msms_peaks / signal_to_noise / top_fragments)
- 前提
- なし
- 状態変更
- なし
- 注意
n_msms_peaksは間引き前の元本数。
dcl_find_msmsprecursor m/z(任意で RT)に一致する MS/MS を引く。
- シグネチャ
- dcl_find_msms(precursor_mz, file_path=None, rt=None, mz_tol=0.01, rt_tol=0.2, top_n_peaks=None)
- 入力
precursor_mz、rt(同一 m/z の別溶出ピークを分離)、許容幅- 出力
- 一致した MSDecResult のリスト、または
status="not_found" - 前提
- なし
- 状態変更
- なし
- 注意
- 該当ゼロは「MS/MS 未取得」であって「フラグメント不在」ではない。同定を否定する根拠にしない。
3参照ライブラリ(MS/MS スペクトル照合)
library_load → library_match_feature → library_plot_mirror の 1 本道。
library_load参照ライブラリを解決し、照合用 SQLite store を構築(またはキャッシュ再利用)する。書込
- シグネチャ
- library_load(file_path=None, rebuild=False, ion_mode=None)
- 入力
file_path、ion_mode(positive/negative →MSDIAL_MSP_POS/NEG)、rebuild- 出力
- record_count、ion_modes、compound_classes 上位 10、search_params(.dbs 由来のみ)、source_sha256、skipped_no_precursor_mz、records_without_ion_mode、non_utf8_lines、note
- 前提
- なし
- 状態変更
session.library.store/ source_path。last_matchをリセット- 注意
- 解決順: file_path → ion_mode の環境変数 →
*_Loaded.msp2.dbs→ 設定済み環境変数 →*.msp。複数候補はMSP_AMBIGUOUS(更新日時で選ばない)。キャッシュキーは sha256(サイズ・mtime と組で覚えて再計算を省く)。.mspは行ごとに UTF-8 → cp932 → latin-1。
library_match_feature測定 MS/MS(.dcl、全ピーク)を候補と照合し、上位をスコア付き TSV で返す。前提
- シグネチャ
- library_match_feature(precursor_mz, rt=None, ion_mode=None, dcl_file=None, mz_tol=None, ms2_tol=None, rt_tol=None, top_n=5)
- 入力
precursor_mz、rt、ion_mode、dcl_file、許容幅(明示 > store の search_params > 既定)、top_n- 出力
- status(success / not_found / no_candidates)、candidates_table(rank・name・5 指標・total_score)、ranked_by、scoring(rule / use_rt / ms1_tol / rt_tol)
- 前提
library_load- 状態変更
session.library.last_match(座標・alignment・unscored_mz)- 注意
- 並び順は MS-DIAL の
GetTotalScore移植(正規化しない和で 1 を超える)。上流の順位付けタプル全体は再現していないので、1 位の妥当性は対向プロットで確かめる。.dcl を引く窓は常に固定(0.01 Da / 0.2 分)。
library_plot_mirror直近の照合結果から対向プロット(上 = 測定、下 = 参照)を描く。前提
- シグネチャ
- library_plot_mirror(rank=1, output=None, scale='relative', label_policy='auto')
- 入力
rank、output、scale(relative / sqrt / log10)、label_policy(auto / msdial)- 出力
- image: PNG(採点外ピークは灰色、凡例と caption に件数)。payload:
lipidmix.mirror.v2(座標は正規化前の生値) - 前提
library_match_feature(候補 1 件以上)- 状態変更
- なし
- 注意
- precursor がベースピークのスペクトルは
relativeだと診断イオンが潰れるのでsqrtを使う。
4アラインメントのキュレーション
注釈付きスポットを一覧と機械判別で確かめ、ユーザーのフラグを記録して、エクスポートと MS-DIAL の _tags.xml に返す(3.1 節・8.4 節)。
curation_review注釈付きスポットの証拠を集めて機械判別し、ビューア HTML を書く。LLM には要約 TSV だけを返す。前提書込
- シグネチャ
- curation_review(ontology=None, name_contains=None, file_ids=None, max_traces=12, thresholds=None, file_path=None, max_rows=100)
- 入力
- 対象: 既定は注釈付き全部、
ontology(クラスの一覧)、name_contains(名前の部分一致)。証拠:file_ids(EIC を重ねる試料。.arfに無い ID はエラー)、max_traces(既定 12。代表試料を必ず含む)。判定:thresholds(ppm_pass=5・ppm_borderline=10・dmz_fail_mda=10・drt_pass=0.5・drt_borderline=1.0 分 など。未知のキーはエラー)。max_rows(返す TSV の行数) - 出力
review_id、counts(ok / suspect / likely_wrong)、table(suspect以上とフラグ済みだけの TSV、判定の重い順に先頭max_rows行。列spot_id name ontology adduct verdict reasons ppm dmz_mda drt wdot mpp eic_good trend_z flag)、n_table_rows_total/n_table_rows_shown、クラス別の傾向要約(点数・R²・外れ数)、warnings、html_path- 前提
.arf2(load_dataset/arf2_parser)とlibrary_load(アラインメントと同じフォルダの*_Loaded.msp2.dbsを推奨)- 状態変更
session.curation(直近のreview_idと保存先)。ディスクに<アラインメントのフォルダ>/curation/review-<id>.jsonと.html- 注意
- EIC 系列とスペクトルは返さない(全件はビューアにある)。1 回の上限は 3000 スポット。呼ぶたびに新しい review を作る(非冪等)。参照を引けた割合が半分未満なら別ライブラリを読んでいる疑いを
warningsで出す。
curation_submitユーザーのフラグを記録し、アラインメントの _tags.xml の Misannotation に反映する。前提書込
- シグネチャ
- curation_submit(submission_text=None, review_id=None, flags=None, source='user', file_path=None)
- 入力
submission_text(ビューアの送信用テキストをそのまま。CURATION_SUBMITで始まる行だけを読む)か、review_id+flags=[{spot_id, flag: wrong|suspect|clear, note}]。source(user= ユーザー自身の判断 /llm= LLM の提案にユーザーが同意)、file_path- 出力
recorded、n_wrong/n_suspect(有効フラグの件数)、tags_xml={path, added, removed, created, backup, note}(失敗時はerrorとmessage)- 前提
- その
review_idのレビューがディスクにあること(セッションの記録 → 送信用テキストのarf2_path→file_path→ 既定の.arf2の順に探すので、サーバ再起動の後でも貼り直せば通る) - 状態変更
curation/flags.jsonlへ追記。アラインメントの_tags.xmlの Misannotation(タグ Id 3)をwrongで付け、clearで外す(suspectと他のタグは触らない)。書く前にcuration/tags-backup/へ控え- 注意
- ユーザーの同意なしに呼ばない。不正な要素・同じ
spot_idの二重指定が 1 つでもあれば何も書かない。レビュー後に.arf2が変わっていれば拒否。flags.jsonlが正本で、_tags.xmlへの反映が失敗しても記録は残る。MS-DIAL でプロジェクトを開いたままだと GUI の保存で上書きされるので、閉じてから開き直す。destructiveHint=true。
curation_flags現在のアラインメントで有効なフラグを TSV で返す。前提
- シグネチャ
- curation_flags(file_path=None)
- 入力
file_path(省略時は既定の.arf2)- 出力
alignment_file、n_flags、table(spot_id flag note source ts。スポットごとの最新 1 行、取消済みは除く)- 前提
.arf2(load_dataset/arf2_parser)- 状態変更
- なし
- 注意
- 今の
.arf2の sha256 に付いたフラグだけを数える。flags.jsonlに読めない行があればファイル名と行番号を返して止まる。
curation_view_dataMCP Apps のビューア専用。レビューのスポット証拠を 1 ページずつ返す。LLM は呼ばない。
- シグネチャ
- curation_view_data(review_id, page=0)
- 入力
review_id、page- 出力
review(メタ)、spots(1 ページ 50 件。EIC 系列・対向スペクトルを含む)、page、n_pages- 前提
- レビューがディスクにあること
- 状態変更
- なし
- 注意
- 会話内表示(
ui://ms-data-parser/curation-viewer)用。Claude Desktop のローカル stdio サーバでは_meta.uiが落ちる不具合があり未検証で、ブラウザでhtml_pathを開く経路が主。
8MS-DIAL Console 実行層(生データ → mzTab-M)
GUI で作ったメソッドファイルを使い、MS-DIAL 本体を CLI 実行する手動経路。9 章に詳細。
console_plan実行計画を作り analysis-job.json を生成する。書込
- シグネチャ
- console_plan(dataset_root, method_file=None, polarity='positive', measure='peak_height', omics='lipidomics', save_project=True, timeout_s=21600, lbm_file=None)
- 入力
dataset_root(生データフォルダ)、method_file(省略時は GUI が自動保存した<project>_param_<時刻>.txtから極性一致の最新)、polarity、measure、omics、save_project、timeout_s(6 時間)、lbm_file- 出力
- job_path、解決済みメソッド・LBM・極性、warnings(既存アライメント結果など)
- 前提
- なし
- 状態変更
session.current_job_path、run_dir/effective-method.txt(元ファイルは変更しない)- 注意
- 止まる条件: METHOD_FILE_NOT_GIVEN / METHOD_FILE_CHOICE_REQUIRED / METHOD_FILE_NOT_TEXT(.mdproject/.mddata は ZIP)/ METHOD_FILE_POLARITY_MISMATCH / LBM_NOT_FOUND / LBM_AMBIGUOUS / UNSUPPORTED_AREA_CONSOLE / MSDIAL_EXE_NOT_FOUND / MSDIAL_EXE_NOT_CONSOLE / MIXED_RAW_FORMATS。
console_runMS-DIAL Console を実行する。前提書込長時間
- シグネチャ
- console_run(job_path=None, detach=False)
- 入力
job_path(省略時session.current_job_path)、detach(監視ワーカーを切り離して即座に戻る)- 出力
- status(completed / partial / failed)、終了証跡、生成物の要約。
detach=Trueなら監視ワーカーの pid(pid_of: "worker") - 前提
console_plan- 状態変更
run_dir/execution-result.json、生成物(-o エクスポート先と生データフォルダの 2 か所)- 注意
- 終了コード 0 だけでは completed にしない(主 mzTab-M が一意・構造妥当・有限値あり・予定入力が全て assay に 1 対 1)。同じジョブを別プロセスが実行中なら JOB_BUSY。実データ 60 試料で約 44 分。
console_statusジョブの現在のステータスを返す(読取専用)。
- シグネチャ
- console_status(job_path=None, include_artifacts=False)
- 入力
job_path、include_artifacts- 出力
- status、artifact_count、artifacts_by_role(既定)、include_artifacts=True で path/role/format/root の TSV、execution(save_project / timeout_s)、execution_receipt、server_version、update_available
- 前提
- なし
- 状態変更
- なし
- 注意
- 完了処理はしない(監視ワーカーが確定させる)。旧方式のジョブは生成物の有無だけで完了と判定せず EXECUTION_UNRESOLVED。60 試料で 313 件出るため既定で全文は返さない。
console_prepare_input計測フォーマットが 1 種類だけの入力フォルダを作る。書込
- シグネチャ
- console_prepare_input(dataset_root, keep_extension='wiff', out_dir=None)
- 入力
dataset_root、keep_extension、out_dir(省略時<元>_<拡張子>)- 出力
- 作成したフォルダと集めたファイル数
- 前提
- なし
- 状態変更
- なし
- 注意
- MIXED_RAW_FORMATS の解消手段。指定拡張子と随伴ファイル(.wiff.scan / .timeseries.data 等)だけをハードリンク(別ボリュームならコピー)。フォルダ形式も扱う。元フォルダは一切変更しない。
console_method_template既存パラメータから別極性用のメソッドファイルを作る。書込
- シグネチャ
- console_method_template(out_path, polarity, based_on=None, dataset_root=None, omics='lipidomics')
- 入力
out_path、polarity、based_on(省略時は候補から 1 件なら採用)- 出力
- 作成したファイルと差し替えた項目
- 前提
- なし
- 状態変更
- なし
- 注意
- まず
console_planの method_file 省略を試す。差し替えるのはIon modeとSearched adduct ionsだけで、空のLbm file pathも解決して埋める。候補が複数なら METHOD_FILE_CHOICE_REQUIRED。
console_method_candidates使えるメソッドファイルの候補を列挙する。
- シグネチャ
- console_method_candidates(dataset_root, polarity=None, omics='lipidomics', search_dirs=None)
- 入力
dataset_root、polarity、search_dirs- 出力
- 候補ごとに origin(same_dir / sibling / past_run / given)、usable(direct / needs_polarity_conversion)、key_params(10 件以下のとき)
- 前提
- なし
- 状態変更
- なし
- 注意
- 探すのは dataset_root 直下 → 兄弟フォルダ直下 → 過去 run が使ったメソッド。再帰しない。
console_cleanupあるジョブが生成したファイルだけを一覧・削除する。書込
- シグネチャ
- console_cleanup(job_path=None, dry_run=True)
- 入力
job_path、dry_run(既定 True)- 出力
- 削除対象(または削除した)一覧、warnings
- 前提
- なし
- 状態変更
- 削除後のジョブ status は
cleaned - 注意
- 消すのは
analysis-job.jsonが記録した生成物だけで、タイムスタンプの推測はしない(記録なしは NO_JOB_OUTPUT)。生データには触れない。監視ワーカーが実行中なら JOB_BUSY。
job_listdataset_root/runs/ 以下のジョブを新しい順に返す。
- シグネチャ
- job_list(dataset_root)
- 入力
dataset_root- 出力
- ジョブ一覧
- 前提
- なし
- 状態変更
- なし
9DatasetState(mzTab-M 経路)
mzTab-M 2.0 を正準状態として読み、ARF 経路と同じ前処理・PCA・差次的解析を回す。session.dataset は独立スロット。
dataset_loadmzTab-M 2.0 を読み session.dataset を作る。書込
- シグネチャ
- dataset_load(mztab_path=None, job_path=None, pipeline_path=None, allow_incomplete=False)
- 入力
mztab_path/job_path/pipeline_pathのいずれか 1 つ、allow_incomplete- 出力
- 要約: 特徴数・試料数・定量尺度、検出状態の行、同定の出所内訳(SME / SML のみ / なし)、inchikey_coverage、source_verification(verified / legacy_unverified / direct_unverified)、warnings
- 前提
- なし
- 状態変更
session.dataset(pipeline_path なら試料対応表・binding・解析行列も同じ run から)- 注意
- 隣接
.arfが同一アライメントだと数値で検証できたときだけ検出状態を取り込む。completed 以外のジョブは INCOMPLETE_ANALYSIS_JOB。allow_incomplete=Trueなら探索専用になり、差次的解析とエクスポートは EXPLORATORY_ONLY_DATASET で拒否。
dataset_status現在の DatasetState の概要を返す。前提
- シグネチャ
- dataset_status()
- 入力
- なし
- 出力
- samples(name/role の TSV。
dataset_differentialの群名はこれをそのまま使う)、detection(available・gap-fill 率)、inchikey_coverage、update_available - 前提
dataset_load- 状態変更
- なし
- 注意
available=falseの間は検出率・欠測率を語ってはいけない。
dataset_preprocess定量行列に前処理レシピを適用する(引数は arf_preprocess と同一+検出率)。前提
- シグネチャ
- dataset_preprocess(normalize='none', blank_min_fold=None, drift_correct=False, max_qc_rsd=None, impute='half_min', min_detection_rate=0.0)
- 入力
- レシピ、
min_detection_rate(gap-fill を除いた実検出率。検出状態があるときだけ) - 出力
- report(arf_preprocess と同形)+ detection.n_samples、sample_meta の batch_source / run_order_source
- 前提
dataset_load- 状態変更
session.datasetの前処理済み行列と recipe- 注意
- 注入順とバッチは MTD の MS:4000089 / MS:4000088 から読むので drift_correct が実際に効く。バッチラベルは 2 値以上のときだけ採用(MS-DIAL 既定は全件 1)。
dataset_pca前処理済み DatasetState で PCA を行う。前提
- シグネチャ
- dataset_pca(n_components=5, log_transform=False)
- 入力
n_components、log_transform- 出力
- スコア、寄与率、run_order_correlation、caveats
- 前提
dataset_preprocess- 状態変更
session.dataset.last_pca(ローディング全量)
dataset_differential前処理済み行列で 2 群比較(Welch+BH-FDR)を行う。前提
- シグネチャ
- dataset_differential(group_a, group_b, q_threshold=0.05, log2fc_threshold=1.0, log_transform=True, group_a_label='group_a', group_b_label='group_b')
- 入力
group_a/group_b= サンプル名のリスト(dataset_statusの samples)、閾値、ラベル- 出力
- summary、n_a / n_b、caveats、result_id。正の log2FC は group_b が高い
- 前提
dataset_preprocess- 状態変更
session.dataset.last_differential(全特徴・volcano 点列)- 注意
- 群名から向きを推測しない汎用ツール。pipeline の明示比較(resolve_comparison / run_comparison)の前提検証は経ない。
dataset_export_differential指定した差次的結果を契約 TSV へ書き出す。前提書込
- シグネチャ
- dataset_export_differential(output_path, result_id=None, apply_curation=True)
- 入力
output_path、result_id(省略時は直近)、apply_curation(既定 true)- 出力
- メタ行(result_id / preprocess_id / source_verification / id_space)+ 15 列
- 前提
dataset_differential- 状態変更
- なし
- 注意
- 前処理をやり直した後の古い結果は書かない(STALE_ANALYSIS_RESULT)。一時ファイルから置換して確定。InChIKey は mzTab-M 由来、ontology と msi_level は空欄。キュレーションのフラグは
SMF_IDとMasterAlignmentIDの対応が検証できたときだけ当てる(applied/not_applied/unmapped)。flags.jsonlが読めなければCURATION_FLAGS_INVALID。
dataset_set_sample_metadata実験情報シート(sample-manifest.v1 / v2、TSV)を全件検証してから一括反映する。前提書込
- シグネチャ
- dataset_set_sample_metadata(manifest_path)
- 入力
manifest_path- 出力
- changed_fields、無効化した結果、warnings
- 前提
dataset_load- 状態変更
session.datasetの試料メタデータ- 注意
- 一部だけ適用される状態は作らない(不備があれば何も変えずにエラー)。前処理入力が変われば前処理・PCA・差次を無効化、group だけなら差次だけ。
dataset_build_matrixv2 の解析行列(analysis-matrix.v1)を 1 本作る。前提
- シグネチャ
- dataset_build_matrix(recipe, recipe_id='default')
- 入力
recipe(base / normalize / drift_correct / filter / impute の 5 キー。profile の matrix_recipes と同じ検証)- 出力
- matrix_id(入力 identity の hash)、形状、eligibility の要約、caveats
- 前提
dataset_load- 状態変更
ds.analysis_matrices[matrix_id](値は戻り値に載せない)- 注意
base="internal_standard_ratio"は binding が要るので missing_state。検出状態不明なら filter は not_evaluable で feature を落とさない。
dataset_statistic名指しした解析行列に v2 統計を 1 件実行する。前提
- シグネチャ
- dataset_statistic(specification, matrix_result_id)
- 入力
specification(kind = welch / anova_tukey / pca と群・変換・閾値)、matrix_result_id- 出力
- statistic-result.v1 の要約(effect_size_definition、groups、bh_population、件数)
- 前提
dataset_load+ 登録済みの解析行列- 状態変更
session.dataset.results["stat_<id>"]- 注意
- 行列が無ければ ANALYSIS_RESULT_NOT_FOUND(近い行列で代用しない)。
5pipeline(生データフォルダ起点の統括)
生データフォルダ 1 つを渡すだけで、Console 実行から品質レポートまでを 1 本の永続 run として進める。
pipeline_run入力検査・計画保存・worker 起動までを一括で行い、短時間で pipeline_path を返す。書込長時間
- シグネチャ
- pipeline_run(dataset_root, request=None, request_id=None)
- 入力
dataset_root、request(target / polarity / method_file / sample_manifest / preprocess / comparisons …)、request_id(冪等性キー)- 出力
- receipt: pipeline_path、status、launch.handshake、needs_input
- 前提
- なし
- 状態変更
<pipeline_root>/pipeline-run.json、worker プロセス- 注意
- 優先順位は request の明示値 >
analysis-request.json> 既定値(preprocess は子キー単位)。同一内容の再送は同じ結果、別内容は IDEMPOTENCY_CONFLICT。壊れた実験情報シートは Console を起動せず needs_input。
pipeline_planpipeline_run と同じ入力検査・計画保存だけを行い、worker を起動しない。書込
- シグネチャ
- pipeline_plan(dataset_root, request=None, request_id=None)
- 入力
- 同上
- 出力
- receipt + resolved(method の source_path・sha256、LBM、polarity の value・source)
- 前提
- なし
- 状態変更
- pipeline-run.json(status planned / needs_input)
pipeline_statusrun の状態を読む(読取専用)。
- シグネチャ
- pipeline_status(pipeline_path, include_details=False)
- 入力
pipeline_path、include_details- 出力
- status、stage_statuses、needs_input、warnings、running なら observed_health(ok / worker_missing / unknown)と recovery_hint
- 前提
- なし
- 状態変更
- なし
- 注意
- 生存確認に失敗しても status は変えず別軸で返す。呼ばなくても worker は最後まで進める。
pipeline_resume入力訂正・下流の再計算・中断した工程からの再開を行う。書込長時間
- シグネチャ
- pipeline_resume(pipeline_path, updates=None, request_id=None, rerun_upstream=False)
- 入力
updates(target / sample_manifest / preprocess / comparisons に限定)、rerun_upstream- 出力
- receipt(新 revision、pending に戻した stage)
- 前提
- なし
- 状態変更
- 新しい attempt / revision を記録
- 注意
- rerun_upstream=True を明示しない限り Console は再実行しない(自動再試行なし)。再実行時は新しい attempt ディレクトリ。
pipeline_cancel取消要求を保存する。書込
- シグネチャ
- pipeline_cancel(pipeline_path)
- 入力
pipeline_path- 出力
- 受理の receipt(停止の確定は pipeline_status で確認)
- 前提
- なし
- 状態変更
- 協調的な取消フラグ(小さな JSON)
- 注意
- 生データを削除しない。二重に呼んでも同じ状態(冪等)。
2実験目的の記録
gap 駆動の文献探索の前提になる目的と小問を analyses/ に保存する。
record_objective確定した実験目的を analyses/<analysis_id>.md に記録する。書込
- シグネチャ
- record_objective(analysis_id, dataset, polarity, groups, comparison, sub_questions, biological_context='', inferred_objective='', confirmed_objective='', expected_biology=None, assay_kind='unknown')
- 入力
- 目的・比較・群・小問 Q1..Qn、
assay_kind(lipid / metabolite / unknown) - 出力
- 保存先と記録内容
- 前提
- なし
- 状態変更
session.assay_kindを切り替え(以後の解釈規則が変わる)
update_objective目的・文脈・状態・assay_kind を更新し、創発的な小問を追記する。書込
- シグネチャ
- update_objective(analysis_id, confirmed_objective=None, biological_context=None, status=None, add_subquestions=None, assay_kind=None)
- 入力
- 更新する項目
- 出力
- 更新後の要約
- 前提
- なし
- 状態変更
- なし
7知識カバレッジ・文献探索・取り込み
小問ごとの知識の穴を見つけ、文献を隔離区画に取り込み、人の確認を経て信頼知識へ昇格させる。12 章に流れ図。
knowledge_coverageobjective の各小問を COVERED / WEAK / GAP に分類する。
- シグネチャ
- knowledge_coverage(analysis_id)
- 入力
analysis_id- 出力
- 小問ごとの分類と根拠ノート。未探索の GAP が自動探索の対象
- 前提
- なし
- 状態変更
- なし
paper_searchEurope PMC を検索し、撤回・重複を除いた候補を返す。net
- シグネチャ
- paper_search(query, max_results=10)
- 入力
query(ユーザー確認済みのクエリ前提)、max_results- 出力
- 候補論文(タイトル・要旨・DOI など)
- 前提
- なし
- 状態変更
- なし
- 注意
- 唯一の外部ネットワーク呼び出し(openWorldHint)。
log_search探索結果を objective の探索ログに記録する。書込
- シグネチャ
- log_search(analysis_id, subquestion, query, hits, promoted=0)
- 入力
- 小問・クエリ・ヒット数・昇格数
- 出力
- 記録結果
- 前提
- なし
- 状態変更
- なし
- 注意
- 既探索の小問の再探索を防ぐ。
ingest_stage関連候補を knowledge/_inbox に speculative として隔離する。書込
- シグネチャ
- ingest_stage(title, abstract, source, found_for, query, relevance_score=None, doi=None)
- 入力
- 出典必須、どの小問のためか
- 出力
- 作成したノートの slug
- 前提
- なし
- 状態変更
- なし
ingest_review_queue_inbox の保留ノートを analysis_id × Qi でグループ化して返す。
- シグネチャ
- ingest_review_queue()
- 入力
- なし
- 出力
- レビュー待ち一覧
- 前提
- なし
- 状態変更
- なし
ingest_promote保留ノートを knowledge/ へ昇格する。書込
- シグネチャ
- ingest_promote(slug, claim_strength='suggested', links=None)
- 入力
slug、claim_strength、links- 出力
- 昇格したノート
- 前提
- なし
- 状態変更
- なし
- 注意
- 信頼知識化の唯一の経路。
ingest_reject保留ノートを破棄する。書込
- シグネチャ
- ingest_reject(slug)
- 入力
slug- 出力
- 結果
- 前提
- なし
- 状態変更
- なし
6図の保存・レポート
通常の対話では PNG ファイルを作らない。利用者が明示したときだけ保存する。
save_pca_figure指定した PCA 結果を reports/figures/ に PNG で保存する。前提書込
- シグネチャ
- save_pca_figure(analysis_id, title=None, source='auto', result_id=None)
- 入力
analysis_id、source(arf / mztab / auto)、result_id- 出力
- 保存先、選ばれた source と result_id
- 前提
- PCA 実行済み(ARF か mzTab-M)
- 状態変更
- なし
- 注意
- 有効な結果が 2 つ以上なら AMBIGUOUS_RESULT_SOURCE(どちらも優先しない)。古い結果は選べない。探索専用データセットの図には但し書きを焼き込む。
save_volcano_figure指定した 2 群比較を volcano PNG として保存する。前提書込
- シグネチャ
- save_volcano_figure(analysis_id, title=None, source='auto', result_id=None)
- 入力
- 同上
- 出力
- 保存先、source、result_id
- 前提
arf_differentialかdataset_differential- 状態変更
- なし
- 注意
arf_plot_volcanoの画像モードと同じ描画関数。
save_eic_figure直近の EIC プロット情報を PNG 化して保存する。前提書込
- シグネチャ
- save_eic_figure(analysis_id, title=None)
- 入力
analysis_id- 出力
reports/figures/<analysis_id>_eic.png- 前提
eic_plot_chromatogramsかeic_plot_compounds- 状態変更
- なし
- 注意
- plot_schema(eic.v1 / eic.multi.v1)で描画関数を選ぶ。
write_report解析・解釈レポートを reports/<analysis_id>.md に上書き保存する。書込
- シグネチャ
- write_report(analysis_id, dataset, body, status='draft', knowledge_refs=None)
- 入力
- 本文 Markdown、status、参照した知識ノート
- 出力
- 保存先
- 前提
- なし
- 状態変更
- なし
read_report過去レポートを読み戻す(最新更新のもの)。
- シグネチャ
- read_report(analysis_id)
- 入力
analysis_id- 出力
- レポート本文
- 前提
- なし
- 状態変更
- なし
list_reports既存レポートの 1 行索引を返す。
- シグネチャ
- list_reports()
- 入力
- なし
- 出力
- analysis_id / date / status
- 前提
- なし
- 状態変更
- なし
1サーバ自身の更新
解析の流れには現れない保守ツール。
server_updateこのクローンを origin/main へ早送りし、requirements.txt が変わったときだけ依存を入れ直す。書込
- シグネチャ
- server_update()
- 入力
- なし
- 出力
- status = up_to_date / updated / updated_with_warning / refused、reason、再起動を促す message
- 前提
- なし
- 状態変更
- なし
- 注意
- プロセスは操作しない(クライアントの再起動は利用者)。未コミット変更・main 以外・早送り不可・オフラインなら何もせず refused。
前処理・QC の計算
解析行列は行 = 試料(assay)、列 = 特徴量で持つ。DatasetState.feature_matrix は(特徴 × assay)で保存され、解析の入口で転置される。v1(ARF ツール・dataset_* ツール・v1 pipeline)と v2(LC–MS メタボロミクス profile)は別の実装で、数値の約束事も違う。この章は v1 を扱い、v2 の行列は 7.6 節で扱う。
6.1 入力行列の組み立て
build_pca_matrix()- 行 = 試料(
FileName)、列 =Spot_<MasterAlignmentID>_<prop>。既定の prop はheight(areaarea_above_baselinem_zrtsignal_to_noiseも可)。 Noneは 0.0。gap-fill 値(MasterPeakID < 0)も値として残すが、検出には数えない。- 残る NaN は列平均で埋め、全 NaN 列は 0。分散 0 の列(ddof=1)は落とす。
min_detection_rate > 0なら「非 gap-fill 試料数 / 全試料数」が閾値未満の列を落とす。- 結果として ARF 経路では
impute前に NaN がほぼ残らず、half_minは事実上何もしない。
build_dataset_pp_inputs()feature_matrixを転置。実験情報シート適用済みならinclude=falseの行を落とす。- role・batch・注入順はシート由来。無ければ role は
detect_sample_roles、batch は MTD の batch label(2 値以上あるときだけ採用)→ ファイル名の 8 桁日付、注入順は MTD の injection sequence label(MS:4000089)。 - 検出率フィルタは前処理の前(
_apply_detection_filter)。gap-fill と実測の区別は正規化・補完のあとでは付かないため。分母はinclude=trueの試料だけ(全 role)。 - 検出状態が無いのに
min_detection_rate > 0ならbad_request(「無い」と「全部未検出」は解釈が正反対)。
役割の判定(sample / qc / blank)
detect_sample_roles() はファイル名と Class ID を _ で区切り、大小無視でトークン照合する。既定トークンは qc と blank。blank を先に評価し、どちらにも当たらなければ sample。detect_qc_strata() は QC 名から 8 桁日付・数字・qc・neg・pos を除いた残りで層を判定し(例 20240311_QC_Cerebellum_ICR_NEG_1 → cerebellum_icr)、層が 2 つ以上なら「全 QC を 1 系列扱いするドリフト補正/RSD は近似」と警告する。
6.2 前処理レシピの実行順
preprocessing.preprocess(matrix, sample_names, roles, run_order, recipe) の実行順。既定は何も適用しない opt-in(ツール既定: normalize="none"、blank_min_fold=None、drift_correct=False、max_qc_rsd=None、impute="half_min")。
steps[*].removed はフィルタごとの独立件数で重なり得るので足し合わせず、総数は features_removed_total を読む。6.3 各ステップの式
step 0 · 失敗 QC 注入の検出 detect_failed_qc(min_ratio=0.2)
失敗注入を残したまま max_qc_rsd を掛けると QC の RSD が全特徴で跳ね上がり、ほぼ全特徴が落ちる(実測: kidney aging NEG で 1345 → 51)。「閾値が厳しすぎる」ように見える現象の真因は QC 側にあることが多いので、arf_exclude で除外して前処理し直す。
step 1 · ブランク除去 blank_filter(min_fold)
blank_min_fold (QC 行は平均に入れない)blank 行か sample 行が無ければ未実施(status="skipped" と caveat)。ツール既定は off、conservative-v1 の auto では 3.0。
step 2 · 正規化 normalize(method)
どの方法も行(試料)ごとの係数で割る: x′ij = xij / fi。v1 に内部標準比は無い(v2 の base="internal_standard_ratio" だけ)。
| method | 係数 fi | 水準の保存 | 注意 |
|---|---|---|---|
tic | Σj xij(NaN 無視) | fi ← fi / median(有効な f) | 総和 > 0 なので疎データでも安全 |
median | medianj xij | 同上 | 未検出 = 0 が過半の試料で 0 になりやすい |
pqn | medianj( xij / refj )、refj = QC 行の median(QC が無ければ全行の median。この段では blank も含む)。refj = 0 は NaN 扱い | 再スケールしない | 積分での事前正規化は無い。report.pqn_reference = qc_median / all_sample_median |
none | — | — | 差次的解析で「未正規化」caveat |
report["unscaled_samples"] と caveat で明示する。旧実装はこの行を NaN で消し、疎データで多数の試料を黙って失っていた。pipeline(conservative-v1)ではこれが 1 件でもあると NORMALIZATION_DEGENERATE で止まる。step 3 · QC ドリフト補正 qc_drift_correct(min_qc=4, window=5)
名前は QC-RLSC に倣うが LOESS ではない。実装は QC を注入順に並べた移動中央値+区分線形補間で、特徴ごとに全ラン 1 系列として補正する(バッチ別の扱いは無い)。
np.interp は QC 区間の外で端値を定数外挿するので、QC を全試料の後にまとめて流した設計(例: 試料 1–48 → Blank 49 → QC 50–56)では補正した外見だけが残る。そのため QC 区間に入る試料が 0 なら未実施、半数未満なら「外挿補正」caveat を付ける(report["qc_interspersion"] の covered / qc_range / sample_range)。未実施になる条件: 注入順を持たない試料がある / 注入順つき QC が 4 本未満 / QC 区間に入る試料が 0(covered == 0)。注入順は ARF 経路では .mddata の analytical_order、mzTab-M 経路では MTD assay[N]-custom[...] の MS:4000089、pipeline では実験情報シート。
step 4 · QC RSD フィルタ qc_rsd_filter(max_rsd)
max_qc_rsd 比率で指定(0.30 = 30%)。QC 2 本未満なら未実施step 6 · 欠損補完 impute(method)
| method | 埋める値 | 備考 |
|---|---|---|
half_min(既定) | 列 j の非 NaN 最小値 / 2 | 0 も最小値に数えるので、0 を含む列は 0 で埋まる。全 NaN 列は 0 |
column_mean | 列平均(旧実装互換) | 全 NaN 列は 0 |
knn | sklearn.impute.KNNImputer(n_neighbors=min(5, max(1, n−1))) | 試料間距離で近傍平均 |
none | 補完しない | NaN が残ると PCA は失敗する |
preprocess に対数変換とスケーリングの段は無い。対数は PCA(log10)と差次的解析(log2(x+1))がそれぞれ下流で掛ける。Pareto スケーリングはコードのどこにも無い。
6.4 pipeline の自動判定 conservative-v1
dataset_service.preprocess_auto が使う方針(lipidmix/analysis/preprocess_policy.py、POLICY_VERSION="conservative-v1")。数えるのは include=true の行だけ。前提が揃わない処理は掛けない側に倒す。
batch_ok
全行に confidence=="confirmed" のバッチがあり、値がちょうど 1 種類。
same_pool
全 QC に確定した qc_pool があり、プールが 1 つ。
¬failed_qc
含める部分行列で detect_failed_qc が失敗注入を出さない。3 つの AND が qc_eligible。
| 項目 | "auto" の解決値 | 条件 | 明示指定したのに前提が無いとき |
|---|---|---|---|
normalize | pqn(満たさなければ none) | qc_eligible ∧ nQC ≥ 3 | QC プールが曖昧か nQC=0 のときだけ拒否。弱い QC で走らせた場合は assumptions.normalize_weak_qc_reference に記録 |
blank_min_fold | 3.0 | nblank ≥ 1 ∧ nsample ≥ 1 | PREPROCESS_PREREQUISITE_MISSING |
drift_correct | True | qc_eligible ∧ nQC ≥ 4 ∧ 全注入順が確定 ∧ 全試料が QC 区間内 | |
max_qc_rsd | 0.30 | qc_eligible ∧ nQC ≥ 3 | |
impute | half_min | 常に | — |
計算のあと・確定の前に check_applied_policy が走り、解決した処理が recipe_applied に無ければ PREPROCESS_STEP_NOT_APPLIED、未正規化試料があれば NORMALIZATION_DEGENERATE、特徴が 0 件なら PREPROCESS_FEATURES_EXHAUSTED で止める。v2 はこの方針を通らず explicit_policy(recipe)(profile-explicit-v2)で profile の指定をそのまま使う。
6.5 caveat の前景化
QC・ブランク・注入順が欠けて飛ばした処理は黙って消えず、report["caveats"] に文言で残る。LLM はこれを解釈結果とレポートの注意点として引用する契約になっている。
- QC も blank も無い → 常に caveat。
- 残存特徴が 0 件 → 「全特徴が除去(閾値が厳しすぎる可能性、解析不能)」。90% 超除去 → 残存割合を注記。
- QC 層が複数 → 1 系列扱いは近似。
- 正規化で未正規化のまま残した試料がある → 件数つきで注記。
- 手動除外(
arf_exclude)が有効 → 0 件でも「ユーザ手動除外: サンプル N 件 / スポット M 件」を必ず開示。
PCA・差次的解析・v2 統計
PCA の正準は lipidmix/analysis/pca.py の run_pca、2 群比較は lipidmix/analysis/differential.py。ARF 経路と mzTab-M 経路は同じ純関数を共有しているので、同じ行列からは同じ数字が出る。
7.1 PCA run_pca(matrix, n_components=None, log_transform=False, scaling="autoscale")
sklearn.decomposition.PCA(既定ソルバの SVD)。成分数 k = min(指定, n, p)、2 未満なら ValueError。NaN の扱いは持たないので入力は補完済みであること。主成分の符号は数学的に反転しうるので、正負そのものではなく試料と特徴の相対関係で読む。| 呼び出し元 | 入力行列 | 成分数 | 返すもの | 補足 |
|---|---|---|---|---|
arf_parser | build_pca_matrix の生行列(フィルタ・除外後) | 全成分 | スコア点列(PC1/PC2)、ローディング上位 | 前処理を経ない探索用 |
arf_pca_preprocessed | session.arf.feature_matrix | components 指定 | 同上+前処理レシピ | QC 点を含む。blank は無い |
dataset_pca | 前処理済み DatasetState | 5 | スコア(4 桁丸め)、寄与率、run_order_correlation | ローディング全量は session.dataset.last_pca だけに持つ |
dataset_statistic(kind="pca") | 名指しした v2 行列 | min(指定 or 5, rank, n−1, p) | スコア、寄与率(6 桁)、sample_ids | 学習行は include ∧ role=sample だけ。非有限・SD 0 の列は除外。ローディングは返さない |
ローディング上位(get_pca_loading_features(top_n=10, n_pcs=2)): PC ごとに係数の大きい側上位 10 と小さい側上位 10 を、MasterAlignmentID・注釈名・m/z・RT つきで返す。注入順相関(dataset_pca): 各 PC スコアと注入順の Pearson r(注入順つき試料 3 以上かつ SD > 0 のとき、3 桁丸め)。|r| ≥ 0.5 なら「PC がドリフトを拾っている」caveat。
7.2 2 群比較(v1)two_group_test
group_a が基準(対照)、group_b が比較対象。特徴ごとに Welch の t 検定を行う。ツール既定は q_threshold=0.05、log2fc_threshold=1.0、log_transform=True。
# log2fc_sign = positive means group_b is higher が宣言する。検定不能になる条件: どちらかの群で有限値が 2 未満、または両群とも分散 0(分母 ≤ 0)→ p=NaN。mean_a / mean_b はどちらのモードでも生値の算術平均を返す。
多重検定補正(Benjamini–Hochberg)bh_fdr
計算例(m = 10)。下から累積最小を取るので、3〜5 位の生値 0.13 / 0.1025 は 5 位の 0.084 に引き下げられる。
| 順位 i | p | p·m/i | q(累積最小) | 判定(0.05) |
|---|---|---|---|---|
| 1 | 0.001 | 0.001×10/1 = 0.0100 | 0.0100 | q ≤ 0.05 |
| 2 | 0.008 | 0.008×10/2 = 0.0400 | 0.0400 | q ≤ 0.05 |
| 3 | 0.039 | 0.039×10/3 = 0.1300 | 0.0840 | |
| 4 | 0.041 | 0.041×10/4 = 0.1025 | 0.0840 | |
| 5 | 0.042 | 0.042×10/5 = 0.0840 | 0.0840 | |
| 6 | 0.060 | 0.060×10/6 = 0.1000 | 0.1000 | |
| 7 | 0.074 | 0.074×10/7 = 0.1057 | 0.1057 | |
| 8 | 0.205 | 0.205×10/8 = 0.2562 | 0.2356 | |
| 9 | 0.212 | 0.212×10/9 = 0.2356 | 0.2356 | |
| 10 | 0.360 | 0.360×10/10 = 0.3600 | 0.3600 |
有意判定と volcano の分類
up = q ≤ 閾値 ∧ log2FC ≥ +閾値、down = q ≤ 閾値 ∧ log2FC ≤ −閾値。- エクスポート 15 列目
significantの判定はexport_contract.is_significant(q, log2fc, …)に一本化されている(q ≤ q_thr ∧ |log2fc| ≥ fc_thr、欠測・NaN は false)。ARF 側はq_value、DatasetState 側はqというキーで同じ量を持つため、判定を経路ごとに置くと 2 実装に分裂する。 - volcano の縦軸は生の p の −log10 で、分類は q で行う。横破線 −log10(q 閾値) は p 軸上の目安であって有意判定と厳密には一致しない。件数は図の点を数えずキャプションや
selection.significant_totalを読む。 summarize_two_group(top_n=15)はn_tested(有限 p の数)・n_significant・n_up・n_downと q 昇順の上位 15 件を返す。全量の volcano 点列はセッションにだけ持つ。
7.3 群の解決と交絡検査
因子トークンによるプール指定。ARF 経路の group_a / group_b は Class ID とサンプル名の両方から因子トークンを解決する(sample_factors.expand_sample_specs)。
| 指定 | 意味 |
|---|---|
group_a="24M", group_b="9w" | 24M_* を全てプールして 9w_* と比べる(多因子デザインで主効果を見る経路) |
group_a="24M_GF" | _ で繋いだトークンは AND(24M かつ GF) |
group_a="ILG_6h", group_b="ILG_0h" | Class ID が同じで、サンプル名の因子(時点)だけ違う 2 群も切り出せる |
| 一致ゼロ・両群が同じ試料を掴む指定 | status="error"(n=0 を成功扱いで返すと「有意 0 件=差なし」と誤読されるため) |
QC・blank は群ラベルを None にしてから展開するので、Class ID が指定トークンを含んでいても(例 QC_24M と group_a="24M")どちらのプールにも入らない。応答の resolved_samples が群の定義そのもの、n_a / n_b が除外後の実 n。mzTab-M 経路の dataset_differential はサンプル名のリストを直接受け、重複除去・未知名と QC/blank の除外・両群の重なり拒否・各群 n ≥ 2(満たさなければ bad_request。ARF 経路は caveat のみ)を行う。
check_confounding。細かい Class ID 単位で見ると各群が単一バッチに見えやすく、健全な設計を交絡と誤報するため、プール後に判定する。pipeline の比較(run_comparison)は交絡を allow_confounded=true の明示なしには実行せず CONFOUNDED_COMPARISON で止める。差次的解析の必須 caveat
- 交絡(群⟂バッチ) — 上図の条件で警告。
- 正規化状態 — レシピに正規化が無ければ「未正規化データの log2FC は測定量差を含み得る」。
- 群サイズ — n < 2 なら「各群 n ≥ 2 が必要」、2 ≤ n < 4 なら小 n(検出力の限界)。
- 退化 — 検定できた特徴が 0 件なら「全特徴で p=NaN。『有意 0 件』を『群間差なし』と解釈しない」。20% 未満しか検定できなくても注記。
differential.one_way_anova()(古典的 F 検定、n < 2 の群は黙って落とす)は関数として残るが未公開。多群は v2 の anova_tukey で、群を実験情報シートで明示したときだけ行う。7.4 v2 統計 dataset_statistic(specification, matrix_result_id)
v2 は名指しした解析行列(analysis-matrix.v1)にだけ統計を掛け、直近の前処理を暗黙に使わない。recipe 違いの行列が 2 本並ぶ前提の設計で、どの行列の数字かを結果に残す。kind は welch / anova_tukey / pca の 3 つだけ(Kruskal–Wallis・Mann–Whitney・対応あり検定・標準化効果量は無く、反復測定は REPEATED_MEASURES_UNSUPPORTED)。
v1 dataset_differential | v2 dataset_statistic(kind="welch") | |
|---|---|---|
| 対象行列 | 直近の前処理済み行列 | matrix_result_id で名指し。無ければ ANALYSIS_RESULT_NOT_FOUND(近い行列で代用しない) |
| 試料の選び方 | 呼び出し側が名前のリストを渡す | include ∧ role=sample ∧ group∈groups。biological_sample_id 必須で重複不可 |
| 変換 | log2(max(x,0)+1)(pseudocount 1) | none か log2。log2 は有限かつ > 0 の値だけ、他は NaN(pseudocount なし) |
| 検定 | Welch(同じ welch_t。t・ν・p は同一式) | |
| 効果量 | 変換空間の平均差 | log2_arithmetic_mean_ratio = log2( mean(生 test) / mean(生 ref) )。どちらかの平均 ≤ 0 なら None |
| BH の母集団 | 有限 p を持つ全特徴 | 検定できた特徴だけ(bh_population に件数) |
| 有意分類 | up / down / ns を付ける | 付けない(閾値は仕様からの反響として記録するだけ) |
| 群サイズ | n ≥ 2(未満は拒否) | n ≥ 2(STATISTIC_GROUP_TOO_SMALL。群を落とさない) |
anova_tukey(multigroup.test_feature)
scipy.stats.f_oneway、群 3 つ以上scipy.stats.tukey_hsd、信頼区間 1−α(α 既定 0.05)。対 (i<j) ごとに mean_j − mean_i・ci・p_adjustedwithin_feature_group_pairs)。特徴間は ANOVA p に BHどれかの群で有限値が 2 未満、または全群で分散 0 なら not_testable。scipy が無ければ STATISTIC_DEPENDENCY_MISSING で止まり、別の検定へ黙って切り替えない。
7.5 v2 の内部標準比・feature binding・QC
内部標準比
ratio = target / standard。分母が有限かつ > 0(検出マスクがあれば実検出)のセルだけ計算し、それ以外は NaN で locked(後段で補完しない)。標準の列は生値のまま support_feature_ids に残る。1 target に標準は 1 つ・自己参照・循環・未知 ID は INTERNAL_STANDARD_MAP_INVALID。内部標準比と normalize ≠ none の併用は MATRIX_RECIPE_INVALID。
feature binding
profile の対象ごとに全 feature を評価: m/z の ppm 誤差 = |obs − exp| / exp × 10⁶、|ΔRT|、同定子(InChIKey・式・CAS・HMDB・KEGG・PubChem。名前は数えない)、要求証拠(mass_rt / library_match / authentic_standard_match)。合格がちょうど 1 件なら resolved、0 件・複数件は FEATURE_BINDING_UNRESOLVED で止め、強度や順番で選ばない。
注入ごとの測定証拠
.arf の AlignedPeakProperties から注入ごとの RT・m/z・検出状態(gap_filled / detected)を読む。スポット数一致と m/z 照合(0.01 Da、外れ 1% 以下、1 Da 超は拒否)で特徴軸を、assay_sources の raw 名で試料軸を確かめ、どちらかが崩れれば部分表を作らず availability=False。
固定母集団 QC
6 指標: pooled_qc_rsd(%、プール×バッチごと、QC 3 本以上)、blank_fold(中央値比)、detection_rate、standard_rt_error、standard_mass_error_ppm、internal_standard_valid_fraction。閾値は profile が与え、コードに数値の既定は無い。集計は P/N ≥ t で pass、(P+U)/N < t で fail、それ以外は評価不可(t 既定 1.0)。
行列の流れ(matrix_state.py): qc_raw が無処理の __raw__ 行列で QC 評価集合をフィルタ前に固定 → preprocess が recipe ごとに make_matrix(補完しない。検出率 filter は列を消さず eligibility_mask だけに効く)→ qc_processed が固定集合で処理後 QC を評価し、落ちた feature を eligibility に反映してから finalize_matrix で補完(locked セルは補完後に NaN へ戻す)。matrix_id は値ではなく入力の identity の hashなので、同じ入力なら同じ ID になる。保存は npz(allow_pickle=False)+メタ JSON で、読むときにメタ hash・配列ごとの SHA-256・形状を検証する。
7.6 結果の鮮度と無効化
result_state.invalidate_results)。結果は preprocess_fingerprint = hash(dataset, recipe, metadata[PP_FIELDS]) と群の指紋で鮮度を持ち、古くなった結果をエクスポート・図保存に渡すと STALE_ANALYSIS_RESULT で止まる。array_fingerprint は dtype・形状・生バイトの SHA-256 なので NaN と 0 は別 hash。同一指紋なら再計算せず再利用する。同定と MS/MS 照合
目的は「付いている名前は本当か」を、人が数値と図の両方で判断できるようにすること。同定名の標準化・同定信頼度の推定・実スペクトルの照合はすべてオフラインで、pygoslin(同梱)と同梱 TSV と参照ライブラリだけを使う。
8.1 verify_peak_annotation の判定の流れ
msi_level() がそれを組み合わせる。アダクト表は [M+H]+ [M+NH4]+ [M+Na]+ [M-H2O+H]+ [M-H]- [M+HCOO]-(= [M+FA-H]-)[M+CH3COO]- [M+Cl]- [2M-H]- [M-2H]2-、元素表は D・F・Br・¹³C を含む。診断フラグメントやクラス固有の MS/MS 規則による検査はしない。ドシエの出力キー: status、identity(id・name・ontology・formula・adduct・observed_mz・rt・ion_mode・S/N)、analytical_checks(mass_error・adduct_consistency・msms)、biological_plausibility(蓄積ノートの語彙ヒットと候補 slug)、identity_normalization(goslin・reference・msi・class_token)、llm_decision(指示文と deterministic_summary、例 msms=PASS)。名前に P- / O- があればエーテル caveat を付け、プラズマローゲンの知識ノートへ繋ぐ。
8.2 名前の標準化(GOSLIN)と参照表
MS-DIAL の限定子を剥がす
no MS2:w/o MS1:w/o MS2:low score:unsettled:を大小無視で除去し、A|Bなら先頭を取る(stripped=True)。RIKEN N-VS1 ID-…のような真の未同定名は解析不能のまま(正しい)。pygoslin で解析
normalize_lipid_nameはparse_ok・normalized・level(SPECIES / MOLECULAR_SPECIES …)・lipid_maps_categoryを返す。未導入でも解析不能でも例外を投げずparse_ok=False。クラストークンで同梱表を引く
reference/lipidmaps_classes.tsv(カテゴリ・メインクラス)とreference/refmet_map.tsv(RefMet 名)はキュレート済みの部分集合で、置き場所はリポジトリ直下のreference/に固定(REFERENCE_DIR。起動ディレクトリに依存しない)。表に無いクラスはmatched=Falseと caveat「同梱マッピング表に無いため ID 未付与」で返し、推測しない。
parse_ok=False は「未同定」でなく「脂質名ではない」)、RefMet/LIPID MAPS 表は脂質のみ、MSI ヒューリスティックは参照しない。質量・アダクト整合だけは再利用できる。8.3 スペクトル照合(MS-DIAL MsScanMatching.cs の忠実移植)
目的は MS-DIAL との数値の一致で、実装の改善ではない。上流の「変な点」(未使用の中間値、両枝が同一の分岐、打ち消える ×999、隣接窓への二重計上を許すカーソル走査、Li et al. 2021 の低エントロピー重みの不在)は意図的にそのまま写してある。
ms2_tol(既定 0.025 Da)。各系列を自身の最大値で割って Im,k・Ir,kid_confidence_measure[4..6] と同じ土俵)−1 は「比較していない」(どちらかのスペクトルが空)、0 は「合わなかった」。混同すると「照合していない」が「合わなかった」に化ける。mzTab の dot product 3 列は上流で −1 を 0 にクランプしてから √ を取るので、比較不能はそこでは 0 として出る。mz_tol / rt_tol、明示 > .dbs の search_params > 既定 0.01 / 0.2)と、.dcl から測定スペクトルを引く窓(常に 0.01 Da / 0.2 分)は別物。.dbs の RtTolerance 既定 100.0 を .dcl 側に流すと、m/z が近い別ピークのスペクトルを黙って拾う。参照ライブラリの store。library_load は .dbs/.lbm2/.msp を読み、元ファイルの sha256 をキーにした SQLite キャッシュ(既定 data/.library-cache)へ初回変換する。precursor m/z を持たないレコードは 1 件ずつ読み飛ばして skipped_no_precursor_mz に数え、極性欄の無いレコードは極性不明として候補に残す(ion_mode 比較は COLLATE NOCASE)。研究室の参照ライブラリは外部流出禁止で、リポジトリの外に置いて MSDIAL_MSP_POS / MSDIAL_MSP_NEG で指す。
8.4 アラインメントのキュレーション(機械判別)
curation_review はスポットごとに 5 系統の帯(PASS / BORDERLINE / FAIL / UNKNOWN)と理由コードを出し、総合判定 verdict にまとめる。画像ではなく数値に対して判定する。MS-DIAL 自身が同定時に出した判定(MsScanMatchResult のフラグ)を主にし、こちらでの再計算は食い違いの検出にだけ使う。UNKNOWN(MS/MS 未取得・参照 RT なし)は不一致に数えない。
| 系統 | 見るもの | 基準 |
|---|---|---|
msms | MS-DIAL の is_reference_matched・脂質規則フラグ、.dcl の実スペクトルでの再照合 | 参照一致なら PASS、MS/MS はあるのに不一致なら FAIL(low_score)、MS/MS なしは UNKNOWN |
mz | 代表試料の m/z − 参照 precursor(引けなければ組成式の理論値) | Δppm 5 / 10、|Δm/z| ≥ 10 mDa、MS-DIAL の precursor 判定、アダクトの電荷と測定極性 |
rt | 代表試料の RT − 参照 RT | 0.5 / 1.0 分 |
eic | 試料ごとの EIC 形状(点数・頂点と半値幅から決まる理想ガウスとの R²・極大の数。最適化を伴う当てはめは使わない)と、頂点 RT の試料間ばらつき | 良い試料の割合 0.5 / 0.2、頂点 RT の標準偏差 0.1 分 |
trend | クラス × 不飽和度ごとの RT–m/z 頑健回帰からの外れ(頑健 z) | z > 3 かつそのクラスの当てはめ R² ≥ 0.7。単独では判定を上げず、他の BORDERLINE と重なったときだけ補強する(不飽和度が上がると線形性が落ちるため) |
| 判定 | 条件 | 理由コード |
|---|---|---|
| likely_wrong | 強い理由が 1 つでも立つ | polarity_mismatch(アダクトの電荷と極性が矛盾)· precursor_unmatched(MS-DIAL の precursor 判定が不一致)· dmz_out(|Δm/z| ≥ 10 mDa)· class_rule_rejected(MS/MS ありで MS-DIAL の脂質クラス規則=診断イオンで棄却) |
| suspect | 強い理由は無く、いずれかの系統が FAIL、または BORDERLINE が 2 つ以上、または BORDERLINE 1 つ + 傾向の外れ | 弱い: ppm_out(Δppm > 10)· low_score · drt_out · eic_poor。帯のみ: ppm_borderline · drt_borderline · eic_borderline · rt_scatter · trend_outlier |
| ok | それ以外 | — |
判定を動かさない情報コードもある: msms_absent · reference_not_found · rescore_discrepancy(こちらの再照合が MS-DIAL の値と 0.1 以上ずれた)· adduct_differs_from_reference · manually_modified · class_rules_not_run(脂質クラス規則が評価されていない=未検証であって誤りではない)· chains_unsupported(鎖レベルの名前なのに is_lipid_chains_match=False。MS-DIAL は照合に失敗しても参照名から | 付きの名前を作るので、| 名は鎖組成の証拠ではない)ほか。
IsLipidClassMatch / IsLipidChainsMatch / IsOtherLipidMatch)は Lipidomics 採点器でしか立たず、他の採点器では全部 false になる。そのまま読むと low score が全件「規則で棄却」に化けるので、対象スポットに規則フラグが 1 件でも true のときだけ 3 コードを使い、無ければ warnings で知らせる。class_rule_rejected が 370 / 404、dmz_out が 139 / 232。MS-DIAL の代表候補の再現は全件一致、参照の解決は 100%、1 回のレビューは約 5〜16 秒。ビューアとフラグの流れ
- 判定根拠のメモ。
likely_wrongとsuspectのカードは、メモ欄の既定値が判定根拠の文になる(例自動: 精密質量 — Δm/z 12.4 mDa(≥10 mDa) / MS2 — 参照と一致せず(low score))。 - 「間違い」の初期選択。
likely_wrongは開いた時点で「間違い」が選ばれた未送信の変更になる。記録済みのフラグがあるもの・人が取り消したもの(flag_cleared)には掛けない。「なし」に戻して送れば取消として記録され、次のレビューで掛け直さない。 - 枠。自動判別の
likely_wrongは赤の破線、記録されて(または人が選び直して)「間違い」になると実線。人の「疑わしい」は橙の実線。 - 対向プロット。ピークの m/z ラベルは
library_plot_mirrorと同じ規則(強度降順の貪欲法、縦横とも重なるものを飛ばす、片側 25 本まで、実測と参照は独立)。縦軸は各側の最大値を 100 とした相対強度で 0 / 50 / 100 の目盛り。 - MS-DIAL への書き戻し。
curation_submitはアラインメントの<stem>_tags.xmlを上流AlignmentResultContainer.Saveと同じ形(<Peak Id="MasterAlignmentID"><Tag>3</Tag></Peak>、UTF-8 BOM・CRLF)で書く。実物の写しで付与 → 除去の往復がバイト一致することを確かめてある。
Console 実行層と pipeline
生データを扱う経路は 2 つある。個々のツールを手で繋ぐ Console 経路と、生データフォルダ 1 つから品質レポートまでを永続 run として自動で進める pipeline 経路。どちらも終了コード 0 だけでは成功と言わず、終了証跡・生成物の構造・試料の 1 対 1 対応まで確かめる。
9.1 Console 経路:計画 → 実行 → 確定
detach=True なら監視ワーカー(python -m lipidmix.console.worker)を切り離して即座に戻る。同期でも切り離しでも同じ execution.supervise を通るので、console_status を呼ばなくても結果は確定する。実データ 60 試料で約 44 分かかり、同期実行では呼び出し元が中断されると生成物ごと失う。ジョブの状態(JobStatus) | 意味 |
|---|---|
| planned | console_plan 直後 |
| running | 監視ワーカーが Console を見張っている |
| needs_input | 人の判断待ち(試料対応表の承認など) |
| completed | 終了証跡・検証とも合格 |
| partial | 生成物はあるが完了条件を満たさない。dataset_load は既定で拒否(INCOMPLETE_ANALYSIS_JOB) |
| failed | 生成物なし |
| cleaned | console_cleanup が記録済み生成物を削除した |
analysis-job.json の主な欄(analysis-job.v2、profile を持つ v2 run は .v3): job_id(job_<日時>_<pos|neg>_<h|a>_<uuid8>)、status、dataset_root、method_file、omics、polarity、measure、run_dir、primary_mztab_files[](path・polarity・measure・sha256・validation・root)、artifacts[](path・role・format・sha256・root)、sample_manifest、warnings、error。run ディレクトリはリポジトリの外(生データ側の runs/)でなければならない(DATASET_ROOT_IN_REPO)。
save_project=true(既定)だと MS-DIAL は全検体の解析とアライメントを終えた後にプロジェクトを書き、その段で読むアセンブリが未署名のローカルビルドだと Windows のポリシーに弾かれる(実測: 41 検体で 13 分半後に失敗)。pipeline は計画時に「ポリシーが Enforce ∧ アセンブリ未署名」を確かめて PROJECT_SAVE_BLOCKED で止める。対処は要求に "save_project": false。9.2 pipeline:受付と worker
mcp_core・lipidmix.tools.* を import しない(AST テストが固定)。走っている最中に届いた pipeline_resume は、worker が stage の境目で要求版の変化に気づいて計画を組み直す(有限回まで、超えると REQUEST_REVISION_CHURN)。9.3 工程(stage)と成果物
| # | v1 stage | やること | 成果物・記録 | 再開時 |
|---|---|---|---|---|
| 1 | prepare_input | 生データ・随伴ファイル・有効メソッドを input/ に配置 | record.inputs | 成功済みなら信じる |
| 2 | upstream | console/attempt-NNNN/ にジョブを作り supervise を直接呼ぶ(cancel_path 付き) | upstream.verification(status・termination・exit_code)。非 completed は MSDIAL_EXECUTION_FAILED | 成功済みなら信じる。やり直しは rerun_upstream |
| 3 | validate_outputs | 生成物の検証、save_project なら GUI プロジェクトを登録 | 無ければ warning GUI_PROJECT_UNAVAILABLE | 成功済みなら信じる |
| 4 | load_dataset | load_dataset_state(job_path) | worker の runtime | 常に再実行 |
| 5 | resolve_metadata | 実験情報シートを読む(無ければ自動生成) | inputs.manifest・manifest_source(シートの内容 hash) | |
| 6 | preprocess | preprocess_auto(conservative-v1) | preprocess 結果 | |
| 7 | pca | PCA と図 | results/pca.png、スコア(ローディングは落とす) | |
| 8 | resolve_comparisons | 比較の前提検証(exploratory では省略) | COMPARISON_REQUIRED / CONFOUNDED_COMPARISON | 結果参照の hash 検証に落ちたら再実行 |
| 9 | differential:<cid> | run_comparison(Welch+BH) | 比較ごとの結果 | |
| 10 | export:<cid> | volcano と契約 TSV | results/volcano_<cid>.png・results/differential_<cid>.tsv | |
| 11 | report(常に最後) | 品質レポート | reports/pipeline-quality-report.md |
v2(stage_plan.BASE_V2_STAGE_IDS): prepare_inputs → execute_console → validate_outputs → load_dataset → resolve_metadata → load_assay_evidence → resolve_feature_bindings → qc_raw → preprocess → qc_processed → statistics:<sid> → export:<sid> → report。成果物は results/feature-table.tsv(+ .annotations.tsv)、results/statistic-<sid>.tsv(+ .tukey.tsv)、quality-report.md。v2 は合成入力と fake Console までしか検証されておらず、routine 目的は PROFILE_VALIDATION_INVALID で止まる(draft profile + execution_purpose="validation" を使う)。
9.4 run の状態遷移
pipeline_status は読取専用で、worker の生存確認に失敗しても status は書き換えず observed_health=worker_missing と recovery_hint を別軸で返す。要求(pipeline-request.v1)の欄と既定値
| 欄 | 既定 | 説明 |
|---|---|---|
target | auto | auto は比較があれば differential、無ければ exploratory |
polarity / method_file / lbm_file | 推定 | Console 経路と同じ解決規則 |
measure | peak_height | peak_height のみ |
timeout_s / save_project / keep_extension | 21600 / true / — | |
sample_manifest | sample-manifest.tsv | 列 sample_id · source_file · role(sample/qc/blank/unknown)· group · batch · injection_order · qc_pool · include。null は「自動生成」 |
preprocess | conservative-v1 | normalize / blank_min_fold / drift_correct / max_qc_rsd = auto、impute = half_min、min_detection_rate = 0 |
comparisons[] | 空 | comparison_id · reference_group · test_group · q_threshold 0.05 · log2fc_threshold 1.0 · log_transform true · allow_confounded false |
再開で変えられるのは target / sample_manifest / preprocess / comparisons だけで、それ以外は NEW_PIPELINE_REQUIRED。値の出所は value_sources(explicit / request_file / default / explicit_update)に残る。run record の results は追記専用で、既存要素の書き換えは拒否される。
再開(prepare_resume)の判断順
見張られていない Console が生きていれば止める
EXECUTION_UNRESOLVED。上流が未完なら明示を求める
rerun_upstreamなしではUPSTREAM_RERUN_REQUIRED。Console の自動再試行はしない。入力と有効メソッドの hash を再検証
変わっていれば
INPUT_CHANGED。更新をマージ
内容が同じなら新しい revision を作らない(
request_id付き再送は直前の結果を返す)。pending に戻す stage を決める
rerun_upstream は全部、シート・前処理・目標の変更は比較以降と report、比較の変更はその比較の stage だけ。同じパスのシートを書き直した訂正も
manifest_sourceの hash で検出する。
エクスポートイメージ
ツールが返すもの・書き出すものの見本。列名・メタ行の順序・書式・ファイル名は実装どおりで、例示値 の付いた数値と化合物名は説明用の架空の値。
10.1 差次的エクスポート(契約 v1、別リポ massbank-context との契約)
arf_export_differential と dataset_export_differential は同じ関数(export_contract.build_meta / format_row)で書く。列の追加・改名・並べ替えは CONTRACT_VERSION の引き上げと下流の同時更新なしにしてはいけない。メタ行の順序も契約の一部。
# contract_version = 1 # exported_at = 2026-09-27T05:12:44.918203+00:00 # source_arf = AlignmentResult_2026_05_15_10_13_35_PeakProperties.arf # source_arf2 = AlignmentResult_2026_05_15_10_13_35.arf2 # group_a = control_6h n_a = 4 # group_b = ILG_6h n_b = 4 # log2fc_sign = positive means group_b is higher # q_threshold = 0.05 log2fc_threshold = 1.0 log_transform = true # preprocess = normalize=pqn blank_min_fold=3.0 drift_correct=true max_qc_rsd=0.3 impute=half_min # n_features_total = 1345 n_with_inchikey = 412 n_unannotated = 933 # msi_note = msi_level は .arf2 由来のクラス上限の保守評価で、MS/MS 取得の有無を表さない spot_id name name_source ontology inchikey inchikey_source msi_level mz rt log2fc p_value q_value mean_a mean_b significant 474 SL 33:0;O|SL 17:0;O/16:0 arf2 SL QXKZ…-UHFFFAOYSA-N arf2 3 580.4221 9.8812 2.418733 3.1e-05 0.0102 18342.5 98221.7 true 1248 PC 16:0_18:1 arf2 PC WTJK…-JQQJRHCPSA-N arf2 3 804.5760 7.0214 -1.302114 0.00041 0.0467 412330 166904 true 2031 TG 52:2 arf2 TG CEJY…-KFDAUHNHSA-N arf2 3 876.8015 12.4430 0.412008 0.182 0.611 1.20e+06 1.61e+06 false 3107 FA 18:2 arf2 FA OYHQ…-HZJYTTRNSA-N arf2 3 279.2330 3.1120 0.023117 5220.1 5301.4 false
| # | 列 | 書式 | 意味 |
|---|---|---|---|
| 1 | spot_id | 整数 | ARF: MasterAlignmentID / mzTab-M: SMF_ID(メタ行 # id_space = mztab_smf_id) |
| 2 | name | 文字列 | 代表名 |
| 3 | name_source | arf2 / mztab_sme / mztab_sml | mztab_sml は MS1 照合のみ。行単位で出所を 1 つに決める(InChIKey を供給した側) |
| 4 | ontology | 文字列 | 脂質クラス。mzTab-M 経路は空欄 |
| 5 | inchikey | 文字列 | 下流の結合キー。無い行は本文から外す(件数はメタ行) |
| 6 | inchikey_source | arf2 / database_identifier / inchi_derived / smiles_derived | どこから導出したか |
| 7 | msi_level | 整数 / 空 | ARF2 のクラス上限推定。mzTab-M 経路は常に空欄(「この経路では取得していない」) |
| 8–9 | mz rt | .4f | 代表 m/z、RT(分) |
| 10 | log2fc | .6f | 正 = group_b が高い |
| 11–12 | p_value q_value | .6g | Welch の p、BH の q |
| 13–14 | mean_a mean_b | .6g | 各群の生値の算術平均 |
| 15 | significant | true / false | is_significant()。非有限は false |
# curation = <state> curation_flags = N[ curation_wrong_excluded = N curation_suspect = N] curation_flags_sha256 = <hex> が 1 行足される(角括弧内の件数は applied のときだけ。15 列の契約自体は変えないので CONTRACT_VERSION は据え置き。下流の meta パーサは未知キーを保持するだけ)。state は applied(wrong を同定なしとして本文から外した)/ not_applied(apply_curation=false)/ unmapped(mzTab-M 経路で ID の対応を検証できず当てていない)。suspect は行も値も変えない。フラグが 0 件なら何も足さず、出力はキュレーション導入前と完全に同じ。pipeline_run が書くエクスポートにはフラグを当てない。NaN・inf・None は文字列化せず空セルにする(上の 4 行目: 両群とも分散 0 で検定不能なので p と q が空)。有意行だけでなく InChIKey が付いた全行を出すのは、下流の濃縮解析が「検出された化合物」を背景に取るため。mzTab-M 経路のメタ行には source_mztab / source_job / source_verification / result_id / preprocess_id が入り、前処理条件は現在の状態ではなくその結果自身の来歴から書く。
10.2 図
normalize="per_trace_max" で系列ごとの最大値を 1 にできるlipidmix.volcano.v1 payload(output="payload")
{"plot_schema":"lipidmix.volcano.v1","title":"Volcano (control_6h vs ILG_6h)",
"axes":{"x":{"label":"log2 fold change"},"y":{"label":"-log10 p"}},
"comparison":{"group_a":"control_6h","group_b":"ILG_6h","n_a":4,"n_b":4},
"thresholds":{"q":0.05,"log2fc":1.0},
"points":[{"feature":"Spot_474_height","log2fc":2.4187,"neg_log10_p":4.5086,"sig":"up"}, …],
"render_hints":{"color_by":"sig","guides":{"x":[-1.0,1.0],"y":[1.3010]}},
"selection":{"total":1345,"plotted":846,"significant_total":46,"significant_plotted":46,
"ns_total":1299,"ns_plotted":800,"max_points":800,"dropped_nonfinite":0}}
payload では up/down を全件残し、ns だけを等間隔で決定的に間引く。selection.plotted < total のとき図は全点ではないので、有意件数は必ず significant_total を読む。dropped_nonfinite は「有意でない」ではなく検定不能(分散 0・欠損・片群のみ検出)。
10.3 ツールの戻り値の形
# batch_source = filename_date sample role group batch run_order excluded 20220901_RAW_control_0h_1_NEG sample control 20220901 3 false 20220901_RAW_LPS_6h_2_NEG sample LPS 20220901 11 false 20220901_QC_01_NEG qc QC 20220901 1 false 20220901_Blank_01_NEG blank Blank 20220901 0 false 20220902_RAW_ILG_6h_1_NEG sample ILG 20220902 27 true
rank name adduct total_score weighted_dot_product simple_dot_product reverse_dot_product matched_peaks_percentage matched_peaks_count entropy_similarity
1 PC 16:0_18:1 [M+H]+ 2.6143 0.8921 0.9104 0.9337 0.8333 5 0.7412
2 PC 18:1_16:0 [M+H]+ 2.5980 0.8874 0.9051 0.9290 0.8333 5 0.7388
3 PE 19:0_18:1 [M+H]+ 1.4410 0.2105 0.3310 0.2892 0.2500 1 0.1934
scoring = {rule: MS-DIAL GetTotalScore, use_rt: false, ms1_tol: 0.01, rt_tol: null}
{"status":"success","group_a":"control_6h","group_b":"ILG_6h","n_a":4,"n_b":4,
"resolved_samples":{"a":["…control_6h_1…", …],"b":["…ILG_6h_1…", …]},
"summary":{"n_tested":1345,"n_significant":46,"n_up":28,"n_down":18,
"top":[{"feature":"Spot_474_height","spot_id":474,"name":"SL 33:0;O|SL 17:0;O/16:0","name_source":"arf2","log2fc":2.4187,"q":0.0102}, …]},
"caveats":["交絡: 各群が単一バッチ(control=20220901, ILG=20220902)。処理効果と測定バッチを分離できない",
"小n: 各群 n<4 のため検出力に限界"],
"volcano_note":"全特徴の点列は session に保持。図は arf_plot_volcano"}
10.4 pipeline が書くもの
pipeline_3f9c…/ ├─ pipeline-run.json # run record(pipeline-run.v1) ├─ requests/revision-0001.json # 要求の各版 ├─ control/ │ ├─ worker.lock pipeline.lock │ ├─ cancel-request.json # 取消フラグ │ └─ worker-launch.log ├─ input/ # 生データのリンク+有効メソッド ├─ console/attempt-0001/ # attempt ごとに分ける │ ├─ analysis-job.json │ ├─ execution-result.json # 終了証跡 │ ├─ worker.json msdial.log │ └─ msdial/*.mzTab … ├─ results/ │ ├─ pca.png │ ├─ volcano_<cid>.png │ └─ differential_<cid>.tsv # 契約 v1 └─ reports/pipeline-quality-report.md
{"schema":"pipeline-run.v1",
"identity":{"pipeline_id":"3f9c…","source_root":"D:/raw/NEG", …},
"request":{"revision":2,"request_id":"req-0927-a",
"content_hash":"sha256:…","effective_target":"differential"},
"status":"completed","state_revision":41,
"stages":{"upstream":{"status":"succeeded","attempt":1, …},
"differential:ilg_vs_ctrl":{"status":"succeeded","result_refs":[…]}},
"upstream":{"verification":{"status":"completed",
"termination":"exited","exit_code":0}},
"results":[…], // 追記専用
"needs_input":null,"warnings":[…],
"worker":{"identity":{…},"started_at":"…"}}
# Pipeline quality report status_at_report_time: completed · reason_codes: [] 自動の生物学的解釈は含まない。 ## Source D:/raw/NEG · 41 raw files (.wiff) ## Method / LBM / version param_20260915.txt (sha256 …) · Lipids.lbm2 · MS-DIAL 5.x ## Execution evidence termination=exited exit_code=0 · execution_id … · mzTab sha256 一致 ## Sample provenance role/group: sample-manifest.tsv · batch: manifest · injection_order: manifest ## Applied / skipped steps normalize=pqn ✓ · blank_min_fold=3.0 ✓ · drift_correct ✓ · max_qc_rsd=0.30 ✓ ## PCA PC1 31.4% · PC2 12.0% · run_order_correlation PC1 r=0.12 ## Comparisons ilg_vs_ctrl: n=8/8 · tested 698 · significant 37(up 22 / down 15) ## InChIKey coverage with_inchikey 214 / 714 · identified_by: sme 0 · sml_only 214 · none 500 ## Unverified conditions 注入順が確定していない試料 0 件 …
10.5 v2 の表(feature_export)
| ファイル | 列 |
|---|---|
results/feature-table.tsv(縦持ち) | dataset_id · feature_id · assay_id · matrix_result_id · value · unit · detected · gap_filled · imputed · exclusion_reason |
<stem>.annotations.tsv | feature_id · candidate_rank · identification_status(candidate / ms1_annotation / unidentified)· name · database_identifier · inchikey · adduct · charge · confidence_measure · confidence_value · mz · rt_min |
results/statistic-<sid>.tsv(welch) | feature_id · status · reason · n_reference · n_test · t_statistic · p_value · q_value · log2fc |
| 同(anova_tukey) | feature_id · status · reason · f_statistic · df_between · df_within · p_value · q_value · group_n |
<stem>.tukey.tsv | feature_id · reference_group · test_group · mean_difference · ci_low · ci_high · p_adjusted · alpha |
未同定の特徴も unidentified として 1 行残す(消すと「同定できたものだけの世界」になる)。ms1_annotation は m/z 照合だけで、v2 の required_evidence では library_match も authentic_standard_match も満たさない。
10.6 レポートと目的ノート
--- type: objective analysis_id: licorice-neg-6h confirmed: true status: active assay_kind: lipid --- ## 確定目的 ILG 処置 6h で変動する脂質クラスを特定する ## 推測の根拠 … ## 派生する小問 - Q1: スフィンゴ脂質は ILG で増えるか - Q2: PC/PE 比の変化は膜リモデリングを示すか ## 創発的に追記された小問 ## 探索ログ(search_log) - Q1 · "isoliquiritigenin sphingolipid" · hits 7 · promoted 2
--- type: report analysis_id: licorice-neg-6h dataset: 2_lipidome_lcms/NEG date: 2026-09-27 status: draft knowledge_refs: [sphingolipid-inflammation] --- ## 結果 46 特徴が有意(q≤0.05, |log2FC|≥1)… ## 注意 - 群とバッチが交絡(20220901 / 20220902) - 各群 n=4 ## 図 
想定ユースケース
利用者がチャットで頼むことと、LLM が呼ぶツールの並び。色は経路(3 章の凡例)と同じ。
A. GUI で解析済みのデータを探索し、2 群を比べる
load_datasetが最新バッチを選び、ARF2 概観と生行列 PCA を返す。LLM は目的の候補を 1〜2 個示し、利用者の確認を得てからrecord_objective(assay_kind="lipid")で記録する(GATEWAY)。- PCA で外れた QC を見つけたら
arf_excludeで外す(失敗注入を残すと QC RSD でほぼ全特徴が落ちる)。 arf_preprocess(normalize="pqn", blank_min_fold=3, drift_correct=True, max_qc_rsd=0.3)。飛ばした処理は caveat に残る。arf_differential(group_a="control_6h", group_b="ILG_6h")。Class ID に時点が無くても、サンプル名の因子トークンで 2 群を切り出せる。交絡・小 n の caveat をレポートの注意点に写す。- 画面で見るなら
arf_plot_volcano(PNG が直接返る)、下流のパスウェイ解析へ渡すならarf_export_differential(output_path)。
B. 生データから全自動で品質レポートまで
- 生データの拡張子を見た LLM は、要求そのものを起動の確認とみなして
pipeline_run(dataset_root, request={"comparisons":[{"comparison_id":"ilg_vs_ctrl","reference_group":"control","test_group":"ILG"}]})を呼ぶ。数秒でpipeline_pathが返る。 - worker が Console を回す(数十分)。
pipeline_statusで進捗を見る。呼ばなくても worker は最後まで進める。 - 群がバッチと完全に交絡していれば
CONFOUNDED_COMPARISONの needs_input で止まる。利用者が納得したうえでpipeline_resume(updates={"comparisons":[{…,"allow_confounded":true}]})。Console は再実行されない。図には「UNADJUSTED」の但し書きが焼き込まれる。 - 完了後、
dataset_load(pipeline_path=…)で同じ run の DatasetState・試料対応表を対話セッションへ引き継ぎ、追加の比較や図を作る。
C. 実験情報の誤記を直して再計算する
- 訂正したシートを
dataset_set_sample_metadata(manifest_path)で渡す。全件検証に 1 件でも落ちれば何も変えずにエラーを返すので、直して再送すればよい。 - batch が変われば前処理・PCA・差次的解析が無効化される(
changed_fieldsで確認)。group だけの変更なら PCA は生きる。 - 古い結果をエクスポートしようとすると
STALE_ANALYSIS_RESULTで止まり、取り違えが起きない。pipeline の run なら同じ訂正をpipeline_resume(updates={"sample_manifest":…})で行う(書き直しは内容 hash で検出される)。
D. 上位ヒットの同定を裏取りする
sample_search(specs=["ILG_6h"])で.pai2/.dclの実パスを引き、pai2_parserがスペクトルを充填する。verify_peak_annotationのmsms.bandがPASSなら実スペクトルを見ている。FLAG_ONLYならdcl_find_msmsで確かめる。質量誤差の帯・アダクト整合と合わせて MSI Level 2/3/4 が出る(Level 1 は出さない)。library_load(ion_mode="negative")(研究室ライブラリ)→library_match_feature(precursor_mz, rt)で候補をtotal_score順に並べ、library_plot_mirror(scale="sqrt")で目視確認する。- クロマトグラムの形は
eic_search_by_mz_rangeで spot_id を確かめてからeic_plot_chromatograms。
H. 注釈を一覧で確かめ、誤同定を MS-DIAL に返す
library_load(file_path=".../Dataset_*_Loaded.msp2.dbs")でアラインメントに使ったライブラリを読む(別ライブラリだと参照を引けずwarningsが出る)。curation_review(ontology=["PG"])。LLM は件数とsuspect以上の TSV だけを受け取り、html_pathをユーザーに渡す。- ユーザーはブラウザで開き、赤破線の
likely_wrong(「間違い」が初期選択・メモに根拠)を確かめて直し、「送信用テキストをコピー」してチャットに貼る。 curation_submit(submission_text=…)が記録し、_tags.xmlの Misannotation を付ける。MS-DIAL でプロジェクトを開き直すと GUI に出る。- 以後の
arf_export_differentialはwrongのスポットを同定なしとして外し、メタ行で宣言する。
E. 結果を文献に照らして解釈し、レポートに残す
knowledge_coverageが小問ごとに COVERED / WEAK / GAP を出す。GAP の小問だけ、利用者が確認したクエリでpaper_search(ファイル名由来の語は外へ送らない)。- 関連候補は
ingest_stageで_inboxに speculative として隔離し、log_searchで探索済みを記録。人がingest_promote/ingest_rejectを決める。 - 観測データと文献が食い違えば平均せず、観測を優先して食い違いを明示する。
save_volcano_figureの PNG を貼り、write_reportで保存する。
F. 生データを手で Console に掛ける(極性を足す)
- 候補を列挙し、NEG のメソッドを土台に
console_method_template(polarity="positive")。差し替えるのは Ion mode と Searched adduct ions だけ。 - フォルダに .wiff と .wiff2 が混在していれば
MIXED_RAW_FORMATSなので、console_prepare_input(keep_extension="wiff")でハードリンクの単一形式フォルダを作る。 console_run(detach=True)で待たずに戻り、console_statusで確認。completed になったらdataset_load(job_path=…)。不要になった生成物はconsole_cleanup(dry_run=True)で一覧してから消す。
G. メタボロミクス v2(内部標準比と多群)
- profile(
lcms-profile.v1)が method・依存・対象 feature・QC 方針を決める唯一の情報源。resolve_feature_bindingsが対象を 1 件に決められなければ止まる。 - 対話で recipe を変えた行列を追加で作り、
matrix_idを名指しして統計を掛ける。どの行列の数字かが結果に残る。 - v2 は合成入力と fake Console までしか検証されていない。実データの結論に使う前に
docs/workflow/metabolomics.mdの検証範囲を確認する。
知識蓄積層とリソース
文献由来の知識(knowledge/)と再利用できる解析手順(playbook/)を MCP リソースとして配信し、解析の目的(analyses/)とレポート(reports/)をツールで読み書きする。セッションをまたいで所見が積み上がる。
gap-driven-literature-discovery)。カバレッジは語彙の同義語展開つき文字 bigram Jaccard で、最良 < 0.06 なら GAP、≥ 0.15 かつ established のノートなら COVERED、それ以外は WEAK。paper_search はプレプリントと要旨なしを除き、撤回(Europe PMC の pubType と Crossref)と既存 DOI/PMID/タイトルの重複を落とす。| URI | 種類 | 返すもの |
|---|---|---|
lipidmix://docs/output-format | 静的 | 出力フィールドの意味の共通核(最初に読む)。読むと注意書きのガードが既読になる |
lipidmix://docs/output-format/{topic} | テンプレート | トピック別の定義: arf · arf2 · pai2 · dcl · eic · identity · mztab · library · curation |
lipidmix://knowledge/index | 静的 | 知識ノートの 1 行索引 - slug: description [claim_strength] |
lipidmix://playbook/index | 静的 | 手順ノートの索引 - slug: when_to_use |
lipidmix://knowledge/inbox | 静的 | レビュー待ちの _inbox ノート(found_for・query・score、analysis_id/Qi ごと) |
lipidmix://knowledge/expand/{slug} | テンプレート | ノート本体+1 hop の [[wikilink]] 近傍(本体 5 件・約 15,000 トークンまで。超過分は索引行に格下げ) |
lipidmix://playbook/expand/{slug} | テンプレート | 同上(playbook を先に探す) |
ui://ms-data-parser/curation-viewer | 静的(text/html;profile=mcp-app) | キュレーションのビューア(MCP Apps 用)。curation_review の _meta.ui が指し、証拠は curation_view_data で取る。ブラウザで開く html_path と同じ HTML |
GATEWAY の規則: 目的と生物学的文脈とアッセイ種別を確認してから索引を読み、未解決の小問に答えるノートだけを展開し、どのノートがどの小問に効いたかを明示する。ノート同士が食い違えば両方を source / claim_strength つきで示し、speculative を明示する。これらは硬いゲートではなく指針だが、解釈はゲートを通ることが前提。
エラー契約とコード一覧
失敗は例外ではなく、本文の JSON 封筒で返す(SDK の isError 経路は structuredContent を落とすため)。どの封筒も error.code が機械可読の識別子、message が人と LLM 向けの説明。
{"error":{"code":"missing_state",
"state":"preprocessed_matrix",
"required_tools":["arf_preprocess"],
"message":"前処理後の行列がありません。先に arf_preprocess を実行してください。"}}
state は不透明な文字列として扱う。required_tools は OR の代替で、サーバは実際の生成元を漏れなく列挙する義務がある。
{"error":{"code":"METHOD_FILE_CHOICE_REQUIRED",
"message":"positive のメソッドが無く、negative の候補があります",
"details":{"searched":[…],"candidates":[…]},
"required_tools":["console_method_template"]}}
Console が外部の操作を要するとき(exe 未設定など)は human_action_required と設定手順を封筒に載せる。
| 領域 | コード | いつ |
|---|---|---|
| Console | MSDIAL_EXE_NOT_FOUND MSDIAL_EXE_NOT_CONSOLE | 実行体が未設定 / GUI を指している(--help で確かめる) |
METHOD_FILE_NOT_GIVEN METHOD_FILE_NOT_FOUND METHOD_FILE_NOT_TEXT METHOD_FILE_POLARITY_MISMATCH METHOD_FILE_CHOICE_REQUIRED | メソッドファイルが決まらない・ZIP を渡した・極性が違う・候補が複数 | |
LBM_NOT_FOUND LBM_AMBIGUOUS | 脂質ライブラリが 1 件に決まらない | |
MIXED_RAW_FORMATS INPUT_PREP_FAILED DATASET_ROOT_IN_REPO UNSUPPORTED_AREA_CONSOLE | 入力フォルダの問題、area 指定 | |
MSDIAL_TIMEOUT MSDIAL_NONZERO_EXIT JOB_BUSY JOB_NOT_FOUND JOB_NOT_PLANNED JOB_POST_RUN_FAILED EXECUTION_UNRESOLVED | 実行と確定 | |
NO_JOB_OUTPUT | 削除対象の記録が無い(推測で消さない) | |
| mzTab-M / Dataset | MZTAB_NOT_FOUND MZTAB_STRUCTURE_INVALID QUANTIFICATION_CONFLICT POLARITY_MISMATCH AMBIGUOUS_PRIMARY_MZTAB | 正準の mzTab-M を 1 つに決められない(辞書順にも LLM にも決めさせない) |
INCOMPLETE_ANALYSIS_JOB EXPLORATORY_ONLY_DATASET STALE_ANALYSIS_RESULT AMBIGUOUS_RESULT_SOURCE | 未完了ジョブ・探索専用・古い結果・図の入力元が曖昧 | |
SAMPLE_DESIGN_MISSING COMPANION_ARTIFACT_MISSING ARTIFACT_HASH_MISMATCH DATASET_BAD_REQUEST MATRIX_RECIPE_INVALID NO_ANNOTATED_FEATURES ANALYSIS_RESULT_NOT_FOUND | 設計・付随ファイル・改ざん・引数・行列 | |
| 前処理・比較 | PREPROCESS_PREREQUISITE_MISSING PREPROCESS_STEP_NOT_APPLIED NORMALIZATION_DEGENERATE PREPROCESS_FEATURES_EXHAUSTED QC_PREREQUISITE_MISSING | conservative-v1 / v2 行列の前提と事後検査 |
COMPARISON_REQUIRED CONFOUNDED_COMPARISON | 比較の指定忘れ・完全交絡 | |
STATISTIC_GROUP_TOO_SMALL BIOLOGICAL_SAMPLE_ID_REQUIRED REPEATED_MEASURES_UNSUPPORTED STATISTIC_DEPENDENCY_MISSING | v2 統計 | |
| pipeline | PIPELINE_REQUEST_INVALID IDEMPOTENCY_CONFLICT NEW_PIPELINE_REQUIRED PROJECT_SAVE_BLOCKED | 受付 |
MSDIAL_EXECUTION_FAILED UPSTREAM_RERUN_REQUIRED UPSTREAM_NOT_VERIFIED INPUT_CHANGED PIPELINE_ALREADY_RUNNING REQUEST_REVISION_CHURN STATE_REVISION_CONFLICT | 実行・再開・同時更新 | |
REQUIRED_OUTPUT_MISSING RESULT_INTEGRITY_MISMATCH ANALYSIS_PRECONDITION_MISSING ANALYSIS_PRECONDITION_INVALID PCA_PRECONDITION_MISSING | 完了判定・handler から漏れた前提エラー(needs_input に変換) | |
| v2 profile | PROFILE_VALIDATION_INVALID PROFILE_ADAPTER_UNSUPPORTED FEATURE_BINDING_UNRESOLVED FEATURE_BINDING_OVERRIDE_INVALID | profile と対象 feature の対応付け |
INTERNAL_STANDARD_MAP_INVALID EVIDENCE_UNIT_UNSUPPORTED | 内部標準・測定証拠 | |
| library | MSP_AMBIGUOUS MSP_ENV_NOT_FOUND LIBRARY_NOT_FOUND INVALID_ION_MODE | ライブラリを 1 つに決められない(message に置き場所は入れない) |
| キュレーション | CURATION_FLAGS_INVALID | flags.jsonl に読めない行がある(dataset_export_differential)。curation_* と arf_export_differential は {"status":"error","message","flags_file","line"} で同じ事態を返し、書き出さない。その行を直すか消してから再実行する |
pipeline で needs_input になるのは入力を直せば進める停止(PREPROCESS_PREREQUISITE_MISSING NORMALIZATION_DEGENERATE PREPROCESS_FEATURES_EXHAUSTED COMPARISON_REQUIRED CONFOUNDED_COMPARISON と、_as_needs_input が包む前提エラー)。それ以外の例外は failed(結果があれば partial)になり、traceback はログへ残る。
設定・制約・既知の限界
14.1 起動と環境変数
C:/Python314/python.exe server.py # 既定 stdio。依存は requirements.txt(Python 3.13+) C:/Python314/python.exe -m pytest tests -q # リポジトリルートから python -m lipidmix.library.store --ion-mode negative # 大きな .msp の初回構築を事前に
| 変数 | 既定 | 用途 |
|---|---|---|
LIPIDMIX_DATA_DIR | <repo>/data | データ探索先(load_dataset(directory) で実行時に差し替わる) |
LIPIDMIX_KNOWLEDGE_DIR LIPIDMIX_PLAYBOOK_DIR LIPIDMIX_ANALYSES_DIR LIPIDMIX_REPORTS_DIR | リポジトリ内 | 蓄積先の置き場の上書き用(NAS 共有運用は 2026-09-28 に撤回)。reports は書けなければ DATA_DIR/reports へ退避し、退避したことを返り値で開示 |
LIPIDMIX_TRANSPORT LIPIDMIX_HOST LIPIDMIX_PORT | stdio · 127.0.0.1 · 8000 | HTTP 待受 |
LIPIDMIX_CAVEAT_MODE | digest | off で意味論ダイジェストを止める |
LIPIDMIX_PLOT_OUTPUT | image | 描画系の戻り値。Plotly で自分で描くクライアント(Use-LLLM)は payload |
MSDIAL_EXE MSDIAL_LBM | — | Console 実行体(msdialcui.exe / msdialconsoleapp.exe)と脂質ライブラリ |
MSDIAL_MSP_POS MSDIAL_MSP_NEG | — | 研究室の参照ライブラリ(外部流出禁止。パスを追跡対象に書かない) |
LIPIDMIX_LIBRARY_CACHE_DIR | data/.library-cache | 照合用 SQLite キャッシュ |
LIPIDMIX_PIPELINE_INDEX_DIR | %LOCALAPPDATA%/Lipidmix/pipeline-index | pipeline の冪等性索引 |
14.2 戻り値を小さく保つ決まり
JSON
json_payload()(separators=(",",":")、ensure_ascii=False)。indent=2 は書かない(実測で戻り値の 15〜57% が空白だった)。
表
行が並ぶ一覧は format_spots_as_table() の TSV(列名 1 回、float は約 4 桁、区切りを含むセルは引用符)。
数値
float は丸めてから返す(round_floats() 既定 6 桁、座標は 4 桁)。既定 repr は 17 桁出る。
二重送信を防ぐ
全ツールに structured_output=False。付けないと outputSchema が導出され、同じ内容が content と structuredContent の両方で送られる。
中間データ
座標配列・ローディング全量・全特徴の差次結果・スペクトル座標はセッションに持ち、図保存・エクスポートがそこから読む。
画像
dpi 100 固定。画像トークン ≈ 幅 × 高さ / 750 なので dpi を上げると二乗で増える。
14.3 既知の限界
- 版依存。バイナリリーダは MS-DIAL の内部クラス配置に従う。クラスを変える MS-DIAL のリリースでは
docs/schema/の Key 番号の再確認が要る。 - 多群 ANOVA は v1 では非公開。MS-DIAL のメタデータに因子と水準の対応が無いため。v2 の
anova_tukeyは実験情報シートで群を明示したときだけ。 - 同定確度は報告するだけで仮定しない。MS/MS のフラグと実スペクトルを全経路で区別する。Level 1 は主張しない。スペクトル照合の順位付けは上流のタプル全体を再現していない。
- ドリフト補正は移動中央値+線形補間(LOESS ではない)で、バッチ別の補正は無い。
- ARF 経路では欠損が 0、gap-fill 値もデータとして使うので、
half_minはほぼ効かない。検出率で絞るならmin_detection_rateを使う。 - v2 の検証範囲。合成入力と fake Console まで。実 Console 接続と profile の科学的検証は未了。
- 生成物は追跡しない。
data/analyses/reports/はクリーンチェックアウトに無い。 - キュレーションの会話内表示は未検証。Claude Desktop のローカル stdio サーバでは MCP Apps の
_meta.uiが落ちる(anthropics/claude-ai-mcp#1069)。ブラウザでhtml_pathを開き、送信用テキストを貼る経路が主。 - MS-DIAL は
_tags.xmlを丸ごと書き直す。アラインメントを保存するたびにメモリ上のタグで上書きし、読むのはプロジェクトを開くときだけ。curation_submitの反映は、プロジェクトを閉じてから送り、開き直して確かめる。GUI での表示そのものはまだ確かめていない。 - MS-DIAL で絞り込まれたデータの
likely_wrong。MS-DIAL は同定時に precursor の許容幅を課しているので、precursor_unmatchedはまず立たない。強い理由の大半はclass_rule_rejectedとdmz_out。likely_wrongが少なくても「全部正しい」ではなく、suspectの理由コードを読む。 - 2026-09-27 に解消した食い違い: 同梱参照表を起動ディレクトリに依存せず読むよう修正(以前はリポジトリ外から起動すると ID 付与が黙って全滅していた)。t 値の符号を log2FC と同じ向きに統一。
MCP_INSTRUCTIONSとリソース説明のトピック一覧にmztab/libraryを追加し、テストで固定。library_plot_mirrorの説明をmirror.v2に、ドリフト補正・行列の欠損処理の docstring とコメントを実装どおりに、output_format 文書の log2FC 定義・p 値の計算法・旧ファイル名・スロットの位置を修正。