mcpField
D
datalad

datalad

github.com/kalarislabsその他7343 回インストール4 日前に更新
リポジトリ

datalad について

DataLad は Git と git-annex を基盤とするデータ管理レイヤーで、大容量ファイル、分散ストレージ、ネストしたデータセットを扱います。必要なデータだけを取得し、分析コマンドを機械可読な形で記録して再実行したい研究チーム向けです。

主な機能

  1. 01Git によるデータセットの履歴と構造の管理
  2. 02git-annex による大容量ファイルの管理
  3. 03ファイルやサブディレクトリのオンデマンド取得
  4. 04datalad run によるコマンド入出力の記録
  5. 05datalad rerun による記録済みコマンドの再実行
  6. 06独立した履歴を持つネストしたデータセットの整理

活用シーン

  1. 01全データをダウンロードせずに大規模データセットを扱う
  2. 02分析に必要なファイルだけを取得する
  3. 03データ処理コマンドを記録して再実行する
  4. 04データセットの履歴と annex コンテンツを併せて公開する

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/kalarislabs/research-agent-skills --skill datalad

インストール後、Claude Code で/dataladを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
data-access.md
provenance.md
publishing.md

詳細

DataLad

概要

DataLad は、Git と git-annex の上に構築されたデータ管理レイヤーです。Git はデータセットの構造、小さなテキストファイル、履歴を追跡します。git-annex は大きなファイルのコンテンツを追跡し、各ファイルをキーとして保存して、そのバイト列をローカルリポジトリ内とは限らない場所に保持します。

この分離が最も重要なポイントです。新しくクローンしたデータセットには、完全な履歴とファイル一覧が含まれていますが、データ自体はほとんど含まれていません。100 TB のデータセットでも、数秒でクローンでき、使用容量は数メガバイトです。バイト列は、ファイルごとに datalad get で要求したときにのみ取得されます。

DataLad が追加するもう1つの機能は、来歴管理です。datalad run はコマンドを実行し、その結果を、コマンド、入力、出力を機械可読形式で記録した情報とともにコミットします。datalad rerun はその記録を読み込み、コマンドを再実行します。これにより、「この図はどう作成されたのか」という問いは、考古学のような調査ではなく、コマンドで解決できるようになります。

通常の Git ではなく DataLad を使う場面

次のいずれかに当てはまる場合は、DataLad を使います。

  • ファイルが大きすぎて Git で扱いにくい場合、または全データをディスクに置くことを望まない共同作業者がいる場合。
  • データが複数の場所(ラボのサーバー、クラスターのスクラッチ領域、S3、スーパーコンピューター)にあり、どこにコピーが存在するかを把握する必要がある場合。
  • 分析を再実行できる必要があり、通常のコミットメッセージだけでは十分な証拠にならない場合。
  • DataLad データセットとして配布されている OpenNeuro、DANDI、または datasets.datalad.org の公開データセットを利用する場合。
  • プロジェクト内にほかのデータセットをネストし、それぞれが独立した履歴を保てるようにしたい場合。

リポジトリがコードとテキストだけで、すべてを無理なく Git に収められ、部分的なチェックアウトも必要ない場合は、通常の Git を使います。小規模な純粋なコードリポジトリに DataLad を重ねても、メリットはなく、階層が増えるだけです。

インストール

# git-annex is NOT written in Python but is available from PyPI if you already
# have git itself installed:
uv pip install git-annex
# You can also install it first from the system
# (Debian/Ubuntu: apt install git-annex; macOS: brew install git-annex;
#  conda-forge: conda install -c conda-forge git-annex)
uv pip install datalad
uv pip install datalad-container   # only for containers-run

datalad wtf --section dependencies   # confirm git-annex version is visible

PyPI の git-annex パッケージは、Haskell のソースをビルドするのではなく、Linux、macOS、Windows 向けのビルド済みバイナリを wheel として配布しています。そのため、ほかの Python 依存関係と同じようにインストールでき、DataLad と同じ環境でバージョンを固定できます。ただし、git は同梱されません。

datalad wtf は解決された環境情報を表示するため、動作が不可解に見えるときは、まずこれを実行してください。git-annex が古い、または存在しないことが、分かりにくいエラーの大きな原因です。

DataLad 自体のライセンスは MIT です。git-annex は AGPL の下で提供される別個のツールです。これは、改変した git-annex を再配布する場合にのみ関係し、単に呼び出す場合には関係ありません。

最初に遭遇する落とし穴:ポインターはデータではありません

datalad clone の後、annex 管理対象のファイルは .git/annex/objects/ 内を指すシンボリックリンクとして存在します(Windows や機能が制限されたファイルシステムなど、シンボリックリンクが使用できない環境では、小さなポインターファイルとして存在します)。この時点では、コンテンツはまだダウンロードされていません。

datalad clone https://github.com/OpenNeuroDatasets/ds000001.git
cd ds000001
ls sub-01/anat/            # the file is listed
python -c "import nibabel; nibabel.load('sub-01/anat/sub-01_T1w.nii.gz')"   # fails
datalad get sub-01/anat/sub-01_T1w.nii.gz                                   # now it works

注意すべき失敗のパターンは、ツールがファイルを空、途中で切れている、破損している、「gzip ファイルではない」、または壊れたシンボリックリンクとして報告し、ディスク上のファイルサイズが数百バイトしかない状態です。これはポインターであり、ダウンロードの破損ではありません。データを読み込む前に datalad get を実行し、「ファイルが存在する」だけではコンテンツが存在する証拠として不十分だと考えてください。

分析でディレクトリを使用する前に、明示的に取得します。

datalad get sub-01/                  # everything under a path
datalad get -r .                     # everything, including subdatasets
datalad get -n -r .                  # subdataset structure only, no file content

datalad status --annex はローカルに存在するコンテンツの量を報告し、git annex whereis <path> は指定したファイルを保持しているリポジトリを報告します。whereis は記録された状態を読み取るだけで、リモートには接続しません。そのため、現在の実際の状態ではなく、git-annex が最後に把握した情報を示します。

データセットの検索、サブデータセットの動作、コンテンツを安全に破棄する方法、データセットの修復については、data-access.md を参照してください。

datalad run で来歴を記録する

手法の文脈で DataLad を使う理由は、datalad run にあります。コマンドとその実行結果を同じコミットに保存します。

datalad run -m "extract brain mask" \
  --input "sub-01/anat/sub-01_T1w.nii.gz" \
  --output "derivatives/sub-01_brain.nii.gz" \
  "bet {inputs} {outputs} -m"

各要素の役割と、省略すると問題が起きる理由は次のとおりです。

  • --input は実行前にコンテンツを取得するため、ポインターのままではコマンドが失敗しません。また、依存関係も記録するため、別のマシンで rerun を実行したときに同じ入力を取得できます。
  • --output は、まず対象のロックを解除するか削除します。これにより、git-annex が保護しているコンテンツへの上書きを拒否するのを防ぎます。指定しないと、読み取り専用に見える annex 管理ファイルに対して、同じコマンドを2回目に実行したときに権限エラーが起きることがよくあります。
  • {inputs} と {outputs} は、それぞれの値に展開されます。{pwd}、{dspath}、{tmpdir} も使用でき、{inputs[0]} で個々の項目を指定できます。
  • コミットメッセージには、=== Do not change lines below === と ^^^ Do not change lines above ^^^ の間に JSON 形式の実行記録が含まれます。このブロックを手動で編集しないでください。rerun が解析します。

データセットに未保存の変更がある場合、開始時の状態がクリーンでないと記録の信頼性が損なわれるため、datalad run は開始を拒否します。先に保存するか変更を破棄するか、--explicit を渡して、指定した入力と出力がすべてであることを宣言してください。コミットする前に、--dry-run basic または --dry-run command でコマンドを確認できます。

何も変更しない実行では、datalad save と同様にコミットは作成されません。

再実行
datalad rerun                       # redo the run recorded at HEAD
datalad rerun --report              # show what would be done, change nothing
datalad rerun --script recompute.sh # extract the commands instead of running them
datalad rerun --since <commit> -b check <revision>   # replay a range onto a new branch

ブランチへの再実行(-b)は、再現性をテストする安全な方法です。リプレイ結果は別の場所に記録され、元のブランチとの差分を調べることで、出力が完全に同一に戻ったかどうかを確認できます。

コンテナー

datalad-container 拡張機能を使うと、イメージを一度登録するだけで、その後のすべての実行について、出力を生成したイメージが記録されます。

datalad containers-add fsl --url docker://brainlife/fsl:6.0.4
datalad containers-run -n fsl -m "brain mask in container" \
  --input "sub-01/anat/sub-01_T1w.nii.gz" \
  --output "derivatives/sub-01_brain.nii.gz" \
  "bet {inputs} {outputs} -m"

イメージ自体もデータセットで追跡されるため、ソフトウェア環境は誰かのシェル履歴に残るのではなく、データと来歴の記録とともに保持されます。設定済みのコンテナーが1つだけの場合は、-n を省略できます。

STAMPED の原則と YODA プロジェクトのレイアウト、実行記録の形式、--explicit と --assume-ready の仕様、W3C PROV 形式での来歴のエクスポートについては、provenance.md を参照してください。

変更の保存と確認

datalad status                 # what changed, including subdataset state
datalad save -m "add QC report" path/to/file
datalad save -m "checkpoint" -r                 # recurse into subdatasets
datalad save -m "small text file" --to-git notes.md

datalad save は、データセットの .gitattributes に従って、ファイルごとにコンテンツを Git と git-annex のどちらに保存するかを決定します。コードや、小さなテキストファイルなど、直接読み取れる状態にしておくべきファイルを Git に保存するには、--to-git を指定してください。yoda 手順(datalad create -c yoda)を使うと、code/、README.md、CHANGELOG.md に対してこれが自動的に設定されます。

データセットの作成

datalad create my_dataset               # plain dataset
datalad create -c yoda my_analysis      # analysis layout (code/ tracked in Git,
                                        # README.md and CHANGELOG.md preconfigured)
datalad create -d . inputs/raw          # register a new subdataset under an existing one

-c yoda は、provenance.md で説明されている分析プロジェクトのレイアウトを適用します。-d . を指定すると、新しいデータセットは親のサブデータセットとして登録され、親の中に無関係なリポジトリとして残されることはありません。

公開

DataLad データセットは通常、履歴を Git ホスティングサービスに、アネックスされたコンテンツをストレージリモートに、それぞれ同時に公開します。

datalad create-sibling-github myaccount/mydataset
git annex initremote store type=S3 bucket=my-bucket encryption=none autoenable=true
datalad siblings configure -s github --publish-depends store
datalad push --to github

Git シブリングとストレージシブリングは、意図的に別々のツールで作成します。Git シブリングは Git リモートであり、datalad create-sibling-* はホスティングサービス用のシブリングを処理します。S3 バケット(または WebDAV、SSH ディレクトリ)は git-annex 特殊リモート であり、Git リモートではないため、git annex initremote で作成します。その後、datalad siblings が特殊リモートを検出し、ほかのリモートと同様に扱います。ここで datalad siblings add --url s3://... を使うのは、このセクションが防ごうとしている誤りです。--url は Git リモートの URL ですが、S3 は Git リモートではありません。そのため、後述の push --to github は --publish-depends の処理で失敗します。

--publish-depends は、よくある公開の失敗を防ぐためのものです。つまり、履歴が参照するコンテンツがアップロードされていない Git リポジトリを公開してしまい、共同作業者はクローンに成功するものの、その後のすべての datalad get が失敗するという事態を防ぎます。この依存関係を宣言すると、毎回ストレージシブリングが先に公開されます。

datalad push は Git 履歴と、デフォルト(--data auto-if-wanted)では、対象が必要とするように設定されたアネックスコンテンツの両方を送信します。対象の設定に関係なく、すべてのコンテンツをプッシュするには --data anything を指定します。

RIA ストア、特殊リモート、認証情報の処理、各シブリングが保持する内容の設定については、publishing.md を参照してください。

ディスク容量の解放

git annex whereis sub-01/                 # confirm another copy exists first
datalad drop sub-01/                      # remove local content, keep the pointer
datalad drop --what all --reckless kill <path>   # last resort, destroys data

datalad drop は、コンテンツの別のコピーが存在することを確認できない場合、デフォルトでは処理を拒否します。これは障害ではなく、安全確認です。--nocheck と --if-dirty は非推奨です。現在の指定方法は --reckless availability で、その意味は文字どおりです。--what では、filecontent(デフォルト)、allkeys、datasets、all のいずれかを選択します。

知っておくべき障害モード

症状原因対処法
ファイルを読むと空、途中で切れている、または壊れたシンボリックリンクになっているコンテンツが取得されておらず、ポインターだけが存在するdatalad get <path>
既存の出力に書き込もうとすると「Permission denied」と表示されるgit-annex がアネックスコンテンツを書き込み保護している--output で宣言するか、datalad unlock <path> を実行する
datalad run が実行開始を拒否するデータセットに未保存の変更がある先に datalad save を実行するか、--explicit を指定する
datalad drop が拒否されるコンテンツの検証済みのコピーがほかにない先にシブリングへプッシュするか、--reckless availability を許可する
共同作業者はクローンできるが、すべての get が失敗するコンテンツを含めずに履歴を公開したストレージシブリングを公開し、--publish-depends を設定する
クローンには成功するが、サブデータセットのディレクトリが空になっているサブデータセットはデフォルトではインストールされないdatalad get -n -r . を実行し、その後、必要なパスを get する
コマンドがあり得ない動作をするgit-annex がない、または古すぎるdatalad wtf --section dependencies

詳細なリファレンス

  • data-access.md:公開済みデータセットの検索(registry.datalad.org、OpenNeuro、DANDI、datasets.datalad.org、および /// ショートカット)、クローンと get のオプション、サブデータセットの処理、アネックスコンテンツの状態、ドロップと削除、fsck による修復。
  • provenance.md:STAMPED の原則と YODA レイアウト、実行記録の形式、run と rerun の全オプション、containers-run、および DataLad の来歴情報を W3C PROV にエクスポートする現在の状況。
  • publishing.md:シブリングとそのアクション、create-sibling-* の各バリアント、RIA ストア、特殊リモート、push の動作、認証情報の処理。

関連スキル

bids スキルでは、DataLad を通じて配布される神経画像データセットの多くが整理されている Brain Imaging Data Structure を扱います。一般的なワークフローでは、DataLad で BIDS データセットをクローンし、BIDS ツールで検証した後、datalad containers-run で BIDS-App を実行して、派生データに来歴情報を記録します。

主な情報源

謝辞

このスキルのトピック範囲は、@bcmcpher の MIT ライセンスの datalad-cli プラグイン(コマンドごとに分かれた 19 個のスラッシュコマンドスキル)から一部着想を得ています。ここに記載する文章は独自に執筆したもので、DataLad の上流ドキュメントに基づいています。どちらも DataLad を扱うため内容の重複は避けられませんが、構成、文体、具体的な技術的主張は異なります。

エージェントの運用手順

  1. 環境を確認します。 Python 環境とライブラリのバージョン(python -c "import pkg; print(pkg.__version__)")を確認し、データの形状、型、欠損値を調べます。
  2. 入力を明確にします。 データまたはユーザーに確認し、形式、識別子、パラメーターを確定します。結果を左右する値については推測せず、質問してください。
  3. まず小規模に実行します。 サンプルまたは単一のフォールドで実行し、実行時間とメモリを確認します。
  4. 上記の手順と参考資料を用いて、タスク全体を実行します。
  5. 結果を検証します。 ホールドアウトデータ、固定した乱数シード、適切な指標を使用し、データリークがないか確認します。不確実性(信頼区間、シード間の標準偏差)を報告します。
  6. 報告します。 実行した内容(バージョン、コマンド、パラメーター)、確認した内容、未解決の不確実性を明記します。
このような場合対応
メモリ不足、または実行が非常に遅いサブサンプリング、チャンク単位または遅延評価による計算、モデルサイズの縮小を行い、変更点をユーザーに伝えます。
この手順に記載された関数、フラグ、エンドポイントがインストール済みのバージョンに存在しないインストール済みバージョンのドキュメント(help()、--help、公式ドキュメント)を確認して適宜対応し、ユーザーに伝えます。API を捏造してはいけません。
必須の入力、識別子、パラメーターが曖昧ユーザーに尋ねるか、実行前に前提を明示します。

整合性に関するルール

  • 結果、パラメーター、識別子、引用、統計値を捏造してはいけません。実行または検証できないことは、明確に伝えてください。
  • このセッションで計算していない指標を報告してはいけません。すべての数値について、その算出に使ったコードの経路を示してください。
  • ここに記載されたバージョン固有の詳細は古くなっている可能性があるため、インストール済みバージョンの公式ドキュメントで確認してください。
  • 金銭が発生する操作、共有 GPU またはクラウドクォータを消費する操作、個人データや患者データに触れる操作、元に戻せない操作を行う前に、ユーザーに確認してください。

コメント