lamindb-data-management について
LaminDB は、生物学データを管理、検索、追跡する研究チーム向けのオープンソースデータフレームワークです。バージョン管理、系譜追跡、検索可能なストレージ、生物学オントロジーによる検証を Python API に統合しています。
主な機能
- 01生物学データセットの管理とバージョン管理
- 02解析コードとデータ系譜の追跡
- 03メタデータによる検索と絞り込み
- 04生物学オントロジーによる注釈検証
- 05関連データオブジェクトのコレクション化
- 06実行環境と来歴の記録
活用シーン
- 01マルチオミクスや単一細胞実験データの整理
- 02解析の入力と出力の関係追跡
- 03オントロジーによるデータセットメタデータの標準化
- 04解析ワークフローでの来歴記録
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jaechang-hits/ sciagent-skills --skill lamindb-data-managementインストール後、Claude Code で/lamindb-data-managementを入力して読み込まれたか確認します。
詳細
LaminDB — 生物学データ管理
概要
LaminDB は、生物学向けのオープンソースデータフレームワークです。データを検索可能、追跡可能、FAIR(Findable、Accessible、Interoperable、Reusable)にします。データレイクハウスアーキテクチャ、リネージ追跡、生物学的オントロジーによる検証、そして生ファイルから注釈・キュレーション済みの成果物まで、生物学データセットを管理するための統一された Python API を組み合わせています。
使用する場面
- 生物学データセット(scRNA-seq、空間データ、フローサイトメトリー、マルチモーダル)の管理とバージョン管理
- 計算リネージの追跡(どのコードがどのデータを生成したか)
- 生物学的オントロジー(細胞型、遺伝子、組織、疾患)に基づくデータの検証とキュレーション
- 複数の実験にまたがる、検索可能なデータレイクハウスの構築
- 環境と来歴の自動取得による再現性の確保
- ワークフローマネージャー(Nextflow、Snakemake)または MLOps(W&B、MLflow)との統合
- オントロジーに基づく注釈(Bionty)によるメタデータの標準化
- シングルセル解析パイプライン(クラスタリング、DE)には、代わりに scanpy を使用してください
- データ管理を行わず、オントロジーの検索のみを行う場合は、bionty を直接使用してください
前提条件
pip install lamindb
# With extras for specific data types
pip install 'lamindb[bionty,zarr,fcs]'
セットアップ:使用前にインスタンスの初期化が必要です。
lamin login
lamin init --storage ./my-data --name my-project
# Or with cloud storage:
# lamin init --storage s3://my-bucket --name my-project --db postgresql://...
インスタンスの種類:ローカル SQLite(開発)、クラウド + SQLite(小規模チーム)、クラウド + PostgreSQL(本番環境)。
クイックスタート
import lamindb as ln
ln.track() # Start lineage tracking
# Save an artifact
import pandas as pd
df = pd.DataFrame({"gene": ["TP53", "BRCA1"], "score": [0.95, 0.87]})
artifact = ln.Artifact.from_df(df, key="results/gene_scores.parquet", description="Gene importance scores")
artifact.save()
print(f"Saved: {artifact.uid}, size: {artifact.size}")
# Query artifacts
results = ln.Artifact.filter(key__startswith="results/").df()
print(f"Found {len(results)} artifacts")
ln.finish()
コア API
1. 成果物 — データオブジェクト
成果物は、バージョン管理されたデータオブジェクト(ファイル、DataFrame、AnnData、配列)です。
import lamindb as ln
import pandas as pd
import anndata as ad
ln.track()
# From DataFrame
df = pd.DataFrame({"sample": ["A", "B"], "value": [1.5, 2.3]})
artifact = ln.Artifact.from_df(df, key="experiments/batch1.parquet").save()
print(f"ID: {artifact.uid}, Version: {artifact.version}")
# From AnnData
adata = ad.read_h5ad("counts.h5ad")
artifact = ln.Artifact.from_anndata(adata, key="scrna/batch1.h5ad", description="scRNA-seq batch 1").save()
# From file path
artifact = ln.Artifact("results/figure.png", key="figures/fig1.png").save()
# Load back
df_loaded = artifact.load() # Returns DataFrame/AnnData/etc.
path = artifact.cache() # Returns local file path
# Versioning
artifact_v2 = ln.Artifact.from_df(df_updated, key="experiments/batch1.parquet", revises=artifact).save()
print(f"v1: {artifact.uid}, v2: {artifact_v2.uid}")
print(f"Latest version: {artifact_v2.is_latest}")
# Delete (archive first, then permanent)
artifact.delete(permanent=False) # Archive
# artifact.delete(permanent=True) # Permanent deletion
2. リネージ追跡
再現性のために、来歴を自動的に取得します。
import lamindb as ln
# Start tracking — captures notebook/script, environment, user
ln.track(params={"method": "PCA", "n_components": 50})
# All artifacts created within this block are linked to this run
input_data = ln.Artifact.get(key="raw/counts.h5ad")
adata = input_data.load()
# ... analysis code ...
output = ln.Artifact.from_anndata(adata, key="processed/pca.h5ad").save()
# View lineage graph
output.view_lineage()
ln.finish() # Finalize tracking
3. クエリとフィルタリング
メタデータ、特徴量、注釈に基づいて成果物を検索・フィルタリングします。
import lamindb as ln
# Basic filtering
artifacts = ln.Artifact.filter(key__startswith="scrna/").df()
print(f"Found {len(artifacts)} scRNA-seq artifacts")
# Filter by metadata
recent = ln.Artifact.filter(
created_at__gte="2026-01-01",
size__gt=1000000
).df()
# Filter by annotated features
immune = ln.Artifact.filter(
cell_types__name="T cell",
tissues__name="PBMC"
).df()
# Single record retrieval
artifact = ln.Artifact.get(key="results/final.parquet") # Exact match, raises if not found
artifact = ln.Artifact.filter(key="results/final.parquet").one_or_none() # Returns None if missing
# Full-text search
results = ln.Artifact.search("gene expression PBMC")
# Streaming large files (without full load into memory)
artifact = ln.Artifact.get(key="large_dataset.h5ad")
backed = artifact.open() # AnnData-backed mode
subset = backed[backed.obs["cell_type"] == "B cell"]
4. 注釈と検証
スキーマとオントロジー用語に基づいてデータセットをキュレーションします。
import lamindb as ln
import bionty as bt
# Annotate artifacts with features
artifact = ln.Artifact.get(key="scrna/batch1.h5ad")
artifact.features.add_values({
"tissue": "PBMC",
"condition": "treated",
"organism": "human",
"batch": 1
})
# Validate with schema
curator = ln.curators.AnnDataCurator(adata, schema)
try:
curator.validate()
artifact = curator.save_artifact(key="validated/batch1.h5ad")
print("Validation passed")
except ln.errors.ValidationError as e:
print(f"Validation failed: {e}")
# Standardize cell type names using ontology
adata.obs["cell_type"] = bt.CellType.standardize(adata.obs["cell_type"])
5. 生物学的オントロジー(Bionty)
注釈に使用する、標準化された生物学用語集にアクセスします。
import bionty as bt
# Available ontologies
# bt.Gene (Ensembl), bt.Protein (UniProt), bt.CellType (CL),
# bt.Tissue (Uberon), bt.Disease (Mondo), bt.Pathway (GO),
# bt.CellLine (CLO), bt.Phenotype (HPO), bt.Organism (NCBItaxon)
# Import and search ontology
bt.CellType.import_source()
results = bt.CellType.search("T helper")
print(results.head())
# Get specific term
t_cell = bt.CellType.get(name="T cell")
print(f"Ontology ID: {t_cell.ontology_id}")
# Explore hierarchy
children = t_cell.children.all()
parents = t_cell.parents.all()
print(f"Children: {[c.name for c in children]}")
# Validate a list of terms
validated = bt.CellType.validate(["T cell", "B cell", "Unknown_type"])
# Returns boolean array: [True, True, False]
6. コレクションと整理
関連する成果物をまとめて、一括操作に使用します。
import lamindb as ln
# Create a collection
artifacts = ln.Artifact.filter(key__startswith="scrna/batch_").all()
collection = ln.Collection(artifacts, name="scRNA-seq batches Q1 2026").save()
print(f"Collection: {collection.name}, {collection.n_objects} artifacts")
# Query collection
for artifact in collection.artifacts.all():
print(f" {artifact.key}: {artifact.size} bytes")
# Organize with hierarchical keys
# Convention: project/experiment/datatype/file
# e.g., "immunology/exp42/scrna/counts.h5ad"
主要な概念
コアエンティティモデル
| エンティティ | 目的 | 例 |
|---|---|---|
| Artifact | バージョン管理されたデータオブジェクト | counts.h5ad、results.parquet |
| Run | 1 回のコード実行 | ノートブックの実行、スクリプトの実行 |
| Transform | コード定義(ノートブック、スクリプト、パイプライン) | analysis.ipynb |
| Feature | 型付きメタデータフィールド | tissue、condition、batch |
| Collection | 関連する成果物のグループ | 「実験バッチ」 |
| ULabel | カスタム分類用のユニバーサルラベル | 「high_quality」、「pilot」 |
対応するデータ型
| 形式 | メソッド | 用途 |
|---|---|---|
| DataFrame | Artifact.from_df() | 表形式データ、メタデータテーブル |
| AnnData | Artifact.from_anndata() | シングルセルデータ |
| MuData | Artifact.from_mudata() | マルチモーダルデータ |
| 任意のファイル | Artifact("path") | 画像、FASTQ、カスタム形式 |
| Zarr | zarr extra 経由 | 大規模な配列データ |
| TileDB-SOMA | tiledbsoma extra 経由 | スケーラブルな細胞レベルのクエリ |
track() / finish() パターン
すべての解析セッションは、次のようにラップします。
ln.track(params={"key": "value"}) # Start: captures code, environment, user
# ... analysis ...
ln.finish() # End: finalizes lineage links
一般的なワークフロー
ワークフロー:複数実験のデータレイクハウス
import lamindb as ln
import anndata as ad
ln.track()
# Register multiple experiments
data_files = ["batch1.h5ad", "batch2.h5ad", "batch3.h5ad"]
tissues = ["PBMC", "bone_marrow", "PBMC"]
conditions = ["control", "treated", "treated"]
for i, (file, tissue, condition) in enumerate(zip(data_files, tissues, conditions)):
adata = ad.read_h5ad(file)
artifact = ln.Artifact.from_anndata(
adata, key=f"scrna/batch_{i}.h5ad", description=f"scRNA-seq batch {i}"
).save()
artifact.features.add_values({
"tissue": tissue, "condition": condition, "batch": i
})
print(f"Registered batch {i}: {artifact.uid}")
# Query across all experiments
treated_pbmc = ln.Artifact.filter(
key__startswith="scrna/",
features__tissue="PBMC",
features__condition="treated"
).all()
print(f"Found {len(treated_pbmc)} matching datasets")
# Load and concatenate
import anndata as ad
adatas = [a.load() for a in treated_pbmc]
combined = ad.concat(adatas)
print(f"Combined: {combined.shape}")
ln.finish()
ワークフロー:検証済みデータのキュレーション
import lamindb as ln
import bionty as bt
import anndata as ad
ln.track()
# 1. Import ontologies
bt.CellType.import_source()
bt.Gene.import_source(organism="human")
# 2. Load raw data
adata = ad.read_h5ad("raw_counts.h5ad")
print(f"Raw: {adata.shape}")
# 3. Validate and standardize cell types
validated = bt.CellType.validate(adata.obs["cell_type"].unique())
if not all(validated):
adata.obs["cell_type"] = bt.CellType.standardize(adata.obs["cell_type"])
# 4. Validate gene names
gene_validated = bt.Gene.validate(adata.var_names)
print(f"Valid genes: {sum(gene_validated)}/{len(gene_validated)}")
# 5. Curate and save
curator = ln.curators.AnnDataCurator(adata, schema)
curator.validate()
artifact = curator.save_artifact(key="curated/validated_counts.h5ad")
print(f"Saved curated artifact: {artifact.uid}")
ln.finish()
ワークフロー:Nextflow パイプラインとの統合
- 各 Nextflow プロセスで lamindb をインポートし、
ln.track()を呼び出します ln.Artifact.get(key=...)で入力成果物を読み込み、ローカルパスにキャッシュします- 解析を実行し、
ln.Artifact(...).save()で出力を新しい成果物として保存します ln.finish()を呼び出します。リネージによって入力と出力が自動的にリンクされます
主要なパラメーター
| パラメーター | 機能 | デフォルト | 選択肢 | 効果 |
|---|---|---|---|---|
key | Artifact() | なし | 文字列パス | 階層型ストレージキー(例:"project/data.h5ad") |
description | Artifact() | なし | 文字列 | 人が読める説明 |
revises | Artifact() | なし | アーティファクト | 改訂対象の以前のバージョン |
params | ln.track() | なし | 辞書 | 現在の実行のパラメーター |
organism | bt.Gene.import_source() | なし | "human"、"mouse" | オントロジーの対象生物 |
permanent | .delete() | False | True/False | 完全削除かアーカイブ削除か |
__startswith | .filter() | — | 文字列 | キーのプレフィックスフィルター |
__gte、__lte | .filter() | — | 値 | 以上/以下 |
__contains | .filter() | — | 文字列 | 部分文字列の一致 |
ベストプラクティス
-
解析は必ず
ln.track()/ln.finish()で囲みます:これにより系譜が自動的に記録されます。これを行わないと、アーティファクトに来歴が残りません。 -
階層型キーを使用します:
project/experiment/datatype/file.extの形式で構成します(例:immunology/exp42/scrna/counts.h5ad)。これにより、プレフィックスベースのクエリーが可能になります。 -
アンチパターン — バージョン管理の代わりにデータを複製する:同じデータセットに新しいキーを作成するのではなく、
revises=パラメーターを使って新しいバージョンを作成します。 -
早い段階で検証します:解析の前にスキーマ検証を実行します。メタデータの不備を早期に検出すれば、後続工程でのデバッグ時間を節約できます。
-
標準化にはオントロジーを使用します:自由記述のラベルをオントロジー用語にマッピングします(例:「T helper cell」→ CL:0000912)。これにより、データセットをまたいだクエリーが可能になります。
-
アンチパターン — ファイルサイズを確認せずに大きなファイルを読み込む:まず
.filter().df()を使ってメタデータを調べ、その後、大きなファイルには.load()または.open()(バックドモード)を使います。 -
データの読み込みより先にメタデータをクエリーします:
.filter()で関連するアーティファクトを絞り込んでから、必要なものだけを読み込みます。
よくあるレシピ
レシピ:データセットの一括登録
import lamindb as ln
from pathlib import Path
ln.track()
data_dir = Path("raw_data/")
for fcs_file in data_dir.glob("*.fcs"):
artifact = ln.Artifact(str(fcs_file), key=f"flow_cytometry/{fcs_file.name}").save()
artifact.features.add_values({"assay": "flow_cytometry", "source": "batch_import"})
print(f"Registered: {fcs_file.name} -> {artifact.uid}")
ln.finish()
レシピ:系譜の表示とエクスポート
import lamindb as ln
artifact = ln.Artifact.get(key="results/final_analysis.h5ad")
# View lineage graph (opens in browser or notebook)
artifact.view_lineage()
# Programmatic lineage access
run = artifact.run
print(f"Created by: {run.transform.name}")
print(f"User: {run.created_by.name}")
print(f"Date: {run.created_at}")
print(f"Input artifacts: {[a.key for a in run.input_artifacts.all()]}")
レシピ:オントロジー階層の探索
import bionty as bt
bt.CellType.import_source()
t_cell = bt.CellType.get(name="T cell")
# Explore hierarchy
print(f"Parents: {[p.name for p in t_cell.parents.all()]}")
print(f"Children: {[c.name for c in t_cell.children.all()]}")
# Find all descendants
descendants = t_cell.children.all()
for child in descendants:
grandchildren = child.children.all()
print(f" {child.name}: {[gc.name for gc in grandchildren]}")
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
InstanceNotSetupError | インスタンスが初期化されていない | lamin init --storage ./data --name my-project を実行します |
ln.track() が失敗する | トランスフォームコンテキストがない | REPL ではなくノートブック/スクリプト内で実行するか、transform を明示的に渡します |
アーティファクトの key が競合する | キーがすでに存在する(バージョンではない) | バージョン管理には revises= を使うか、別のキーを選びます |
ValidationError | データがスキーマと一致しない | curator.validate() を実行して具体的な失敗箇所を確認し、用語を標準化します |
| 大規模なインスタンスでクエリーが遅い | フィルター対象フィールドにインデックスがない | まず概要の確認に .df() を使い、頻繁にフィルターするフィールドにはデータベースインデックスを追加します |
| オントロジーのインポートに失敗する | ネットワークの問題、または生物種が正しくない | インターネット接続を確認し、organism="human" を明示的に指定します |
.cache() で FileNotFoundError が発生する | クラウド上のアーティファクトが同期されていない | ストレージへの接続を確認します。メモリー上でアクセスするには、代わりに artifact.load() を使います |
関連スキル
- anndata-data-structure — LaminDB で単一細胞データの主要なデータコンテナーとして使用される AnnData 形式
- scanpy-scrna-seq — 単一細胞解析パイプライン。LaminDB は scanpy が解析するデータを管理します
- scvi-tools-single-cell — 単一細胞向けの深層学習モデル。データ/モデルの追跡で LaminDB と連携します
参考資料
- LaminDB ドキュメント — 公式ユーザーガイドと API リファレンス
- LaminDB チュートリアル — ステップごとの入門ガイド
- Bionty ドキュメント — 生物学的オントロジーの管理
- LaminDB GitHub — ソースコードと課題