DataLad は何をしますか?
概要
DataLad は、Git と git-annex の上に構築されたデータ管理レイヤーです。Git がデータセットの構造、小さなテキストファイル、および履歴を追跡します。git-annex は大規模ファイルのコンテンツを追跡し、各ファイルをキーとして保存し、バイトデータをローカルリポジトリとは限らない場所に保持します。
この分割は、内部化すべき最も重要なポイントです。なぜなら、新しくクローンされたデータセットには完全な履歴と完全なファイル一覧が含まれている一方で、データはほとんど含まれていないからです。100 TB のデータセットは数秒でクローンされ、数メガバイトを占有します。バイトデータは、ファイルごとに datalad get を使って明示的に要求された場合にのみ到着します。
DataLad が追加する二つ目の要素は、来歴(プロビナンス)です。datalad run はコマンドを実行し、その結果をコマンド、入力、出力の機械可読なレコードとともにコミットします。datalad rerun はそのレコードを読み取り、再実行します。これにより、「この図はどのように生成されたのか」という問題が、考古学の問題からコマンド一発の問題に変わります。
通常の Git の代わりに DataLad を使用する場合
以下のいずれかに該当する場合は、DataLad を使用します。
- ファイルが Git で快適に処理するには大きすぎる、または合計サイズがすべての共同作業者がディスクに置きたいサイズを超えている。
- データが複数の場所(ラボサーバー、クラスタスクラッチ、S3、スーパーコンピュータ)に存在し、どのコピーが存在するかを把握する必要がある。
- 分析を再実行可能にする必要があり、単なるコミットメッセージだけでは証拠として不十分である。
- OpenNeuro、DANDI、または
datasets.datalad.orgから公開データセットを利用している。これらは DataLad データセットとして配布されている。 - プロジェクトが他のデータセットを内部にネストしており、それぞれが独立した履歴を保持する必要がある。
リポジトリがコードとテキストのみで、すべてが Git に快適に収まり、部分チェックアウトが不要な場合は、通常の Git を使用します。小さな純粋コードリポジトリに DataLad を追加すると、何も得られないまま間接性が増すだけです。
インストール
# git-annex は Python で書かれていませんが、git 自体がインストールされていれば PyPI から利用可能です。
uv pip install git-annex
# システムから先にインストールすることもできます
# (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 # containers-run にのみ必要
datalad wtf --section dependencies # git-annex のバージョンが表示されることを確認
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/ # ファイルが一覧表示される
python -c "import nibabel; nibabel.load('sub-01/anat/sub-01_T1w.nii.gz')" # 失敗
datalad get sub-01/anat/sub-01_T1w.nii.gz # これで動作する
認識すべき失敗モード:ツールがファイルを空、切り詰められた、破損している、「gzip ファイルではない」、または壊れたシンボリックリンクとして報告し、ディスク上のファイルサイズが数百バイトである。これはポインタであり、破損したダウンロードではありません。データを読み取る前に datalad get を実行し、「ファイルが存在する」ことをコンテンツが存在する十分な証拠として扱わないでください。
分析がディレクトリに触れる前に、明示的に取得します:
datalad get sub-01/ # パス以下のすべて
datalad get -r . # サブデータセットを含むすべて
datalad get -n -r . # サブデータセット構造のみ、ファイルコンテンツなし
datalad status --annex はローカルに存在するコンテンツの量を報告し、git annex whereis <path> は特定のファイルを保持するリポジトリを報告します。whereis は記録された状態を読み取り、リモートに問い合わせないため、現在の真の状態ではなく、git-annex が最後に学習したことを通知します。
データセットの検索、サブデータセットの動作、安全にコンテンツを削除する方法、およびデータセットの修復については、data-access.md を参照してください。
datalad run で来歴を記録する
datalad run は、メソッドのコンテキストで DataLad を使用する理由です。コマンドをその効果とともに、同じコミットに保存します:
datalad run -m "脳マスク抽出" \
--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 が保護しているコンテンツへの上書きを拒否しません。これがないと、同じコマンドの2回目の実行は、読み取り専用のように見えるannexファイルに対する権限エラーで一般的に失敗します。{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 # HEAD に記録された実行をやり直す
datalad rerun --report # 何が行われるかを表示し、何も変更しない
datalad rerun --script recompute.sh # 実行する代わりにコマンドを抽出する
datalad rerun --since <commit> -b check <revision> # 範囲を新しいブランチに再生する
ブランチに再実行する(-b)ことは、再現性をテストする安全な方法です。再生は別の場所に着地し、元のブランチとの差分は、出力が同一に戻ってきたかどうかを示します。
コンテナ
datalad-container 拡張機能を使用すると、イメージを一度登録するだけで、以降のすべての実行がどのイメージが出力を生成したかを記録します:
datalad containers-add fsl --url docker://brainlife/fsl:6.0.4
datalad containers-run -n fsl -m "コンテナ内で脳マスク" \
--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 # サブデータセットの状態を含む、変更点
datalad save -m "QCレポート追加" path/to/file
datalad save -m "チェックポイント" -r # サブデータセットに再帰する
datalad save -m "小さなテキストファイル" --to-git notes.md
datalad save は、データセットの .gitattributes に従って、ファイルごとにコンテンツを Git に保存するか git-annex に保存するかを決定します。--to-git でファイルを強制的に Git に保存できます。これは、直接読み取り可能であるべきコードや小さなテキストファイルに適切な選択です。yoda プロシージャ(datalad create -c yoda)は、code/、README.md、CHANGELOG.md に対してこれを自動的に設定します。
データセットの作成
datalad create my_dataset # プレーンなデータセット
datalad create -c yoda my_analysis # 分析レイアウト(code/ は Git で追跡、
# README.md と CHANGELOG.md は事前設定済み)
datalad create -d . inputs/raw # 既存のデータセットの下に新しいサブデータセットを登録
-c yoda は、provenance.md で説明されている分析プロジェクトレイアウトを適用します。-d . は、新しいデータセットを親のサブデータセットとして登録し、無関係なリポジトリを内部に残さないようにします。
公開
DataLad データセットは通常、履歴用の Git ホスティングサービスと、annex コンテンツ用のストレージリモートの2か所に同時に公開されます。
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 sibling とストレージ sibling は、意図的に異なるツールで作成されます。Git sibling は Git リモートであり、datalad create-sibling-* がホスティングサービス用のものを処理します。S3 バケット(または WebDAV、SSH ディレクトリ)はgit-annex スペシャルリモートであり、Git リモートではないため、git annex initremote で作成されます。datalad siblings はその後、スペシャルリモートを拾い上げ、他の sibling と同様に扱います。ここで datalad siblings add --url s3://... を使用することは、このセクションが防止しようとしている誤りです。--url は Git リモート URL であり、S3 はそうではないため、以下の push --to github は --publish-depends ホップで失敗します。
--publish-depends は、一般的な壊れた公開を防ぎます。つまり、履歴がアップロードされなかったコンテンツを参照している Git リポジトリであり、共同作業者が正常にクローンした後、すべての datalad get が失敗することになります。依存関係を宣言することで、ストレージ sibling が毎回最初に公開されるようになります。
datalad push は、Git 履歴と、デフォルト(--data auto-if-wanted)ではターゲットが欲しがるように設定されているannexコンテンツの両方を送信します。--data anything を渡すと、ターゲットの設定に関係なくすべてのコンテンツをプッシュします。
RIA ストア、スペシャルリモート、認証情報の処理、およびどの sibling が何を保持するかの設定については、publishing.md を参照してください。
ディスク容量の解放
git annex whereis sub-01/ # 最初に別のコピーが存在することを確認
datalad drop sub-01/ # ローカルコンテンツを削除し、ポインタは残す
datalad drop --what all --reckless kill <path> # 最終手段、データを破壊する
datalad drop は、コンテンツの別のコピーを確認できない場合、デフォルトで拒否します。これは障害ではなく安全チェックです。--nocheck と --if-dirty は非推奨です。現在の綴りは --reckless availability であり、その意味はそのままです。--what は filecontent(デフォルト)、allkeys、datasets、all から選択します。
知っておくべき失敗モード
| 症状 | 原因 | 修正方法 |
|---|---|---|
| ファイルが空、切り詰められた、または壊れたシンボリックリンクとして読み取られる | コンテンツが取得されていない。ポインタのみ存在する | datalad get <path> |
| 既存の出力に書き込もうとすると「Permission denied」 | git-annex がannexコンテンツを書き込み禁止にする | --output で宣言するか、datalad unlock <path> を実行 |
datalad run が開始を拒否する | データセットに未保存の変更がある | 最初に datalad save を実行するか、--explicit を渡す |
datalad drop が拒否する | コンテンツの検証済みの2番目のコピーがない | 最初に sibling にプッシュするか、--reckless availability を受け入れる |
共同作業者がクローンしたが、すべての get が失敗する | コンテンツなしで履歴が公開された | ストレージ sibling を公開し、--publish-depends を設定する |
| クローンは成功したが、サブデータセットディレクトリが空 | サブデータセットがデフォルトでインストールされていない | datalad get -n -r . を実行し、次に必要なパスを get する |
| コマンドが不可能な動作をする | git-annex がないか、古すぎる | datalad wtf --section dependencies を実行 |
詳細リファレンス
- data-access.md: 公開データセットの検索(
registry.datalad.org、OpenNeuro、DANDI、datasets.datalad.orgおよび///ショートカット)、clone および get オプション、サブデータセット処理、annex コンテンツ状態、削除と除去、およびfsck修復。 - provenance.md: STAMPED 原則と YODA レイアウト、実行レコード形式、
runおよびrerunオプションの完全版、containers-run、および DataLad の来歴を W3C PROV にエクスポートする現在の状態。 - publishing.md: sibling とそのアクション、
create-sibling-*バリアント、RIA ストア、スペシャルリモート、pushセマンティクス、および認証情報の処理。
関連スキル
bids スキルは、DataLad を通じて配布される神経画像データセットのほとんどが編成されている Brain Imaging Data Structure をカバーしています。典型的なワークフローは、DataLad で BIDS データセットをクローンし、BIDS ツールで検証し、datalad containers-run で BIDS-App を実行して、派生データが来歴を保持するようにします。
主要ソース
- DataLad ドキュメント:https://docs.datalad.org/en/stable/
- DataLad ハンドブック:https://handbook.datalad.org/en/latest/
datalad runの章:https://handbook.datalad.org/en/latest/basics/101-108-run.html- YODA 原則:https://handbook.datalad.org/en/latest/basics/101-127-yoda.html
- STAMPED 原則(YODA から運用化):https://stamped-principles.org
- datalad-container:https://docs.datalad.org/projects/container/en/stable/
- git-annex:https://git-annex.branchable.com/
- データセットレジストリ:https://registry.datalad.org
謝辞
このスキルのトピックスコープは、@bcmcpher の MIT ライセンス datalad-cli に一部基づいています。