Croissantへのセマンティクスの追加
RoboCroissantファイルは、ナレッジベースがどのファイルを持ち、それらがどのカラムを含むかを示します。このスキルは、データが意味するもの、つまり、どのカラムが一緒に遺伝子や疾患を説明するか、行が何を主張するか、カラムのIDがどの識別子プレフィックスを使用するか、コードが何を表すかを追加します。これを、Croissant 1.1コンストラクトを使用して新しいcroissantに書き込み、各ステートメントがなぜ作成されたかを記録します。
あなたは計画(JSON、レイアウトごと)を作成し、スクリプトがそれを適用してチェックします。手動でcroissantを編集することはありません。
入力と出力
- 入力: croissant(
croissant.jsonまたはcroissant.json.gz)と出力ディレクトリ、さらに存在する場合はcroissantの隣にあるメンテナー用のsemantics_answers.json。 - 出力(出力ディレクトリ内):
semantics_plan.json— 計画(形式:reference/plan-format.md)croissant.semantic.json(入力がgzipされていた場合は.json.gz) — 結果check_report.md—check.pyの出力(およびレコードの読み込みに失敗した場合のcheck_report.load_errors.txt、完全なmlcroissantエラー)notes.md— 決定事項、省略されたレイアウトとその理由、ナレッジベースのメンテナーへの質問
入力されたcroissantは決して変更されません。ダウンロード、ヘルパースクリプト、その他の一時的な作業はOUT/work/に配置し、他の場所には配置しないでください。
スクリプト
すべてscripts/にあり、直接実行します(uv run --scriptファイルであり、依存関係を自動的にインストールします)。どのスクリプトでも--helpを使用できます。
| スクリプト | 使用法 |
|---|---|
inventory.py CROISSANT [--layout ID] [--json F] [--common-columns] | レイアウト(異なるカラムセット)を降順に一覧表示、1つのレイアウトのカラム、レコードセット、ファイルを記述、ほとんどのレコードセットが共有するカラムを一覧表示 |
sample.py CROISSANT --layout ID | レイアウトの3つのファイルから実際の行を読み取り、各カラムのサンプル値とその形状(CURIEとそのプレフィックス、ベアID、リスト、コード)を表示 |
dialects.py list/show/detect/read | 既知のファイル形式(VCF、GAF、MITAB、CTD ...)を計算可能な方言として扱う、レイアウトのファイルを読み取るものはどれか、croissantがファイルについて言うことだけを使用してレコードを読み取る |
vocab.py class/slot/search/associations/prefix/identify/term/ols/infores | Biolinkクラスとスロット(ニアミス提案あり)を検索、サブジェクト/オブジェクトペアのアソシエーションクラス、識別子プレフィックス(Biolink + Bioregistry)、ベアIDに適合するプレフィックス、IDまたはテキストによるオントロジー用語、ソース名のinfores ID |
apply_plan.py CROISSANT PLAN OUT | 計画を新しいcroissantに書き込む |
check.py CROISSANT PLAN OUT --report R --load-records | --plan-onlyが最初: 用語、プレフィックス、方言、単位を数秒でチェック。次に完全なチェック: Biolinkとサンプリングデータに対する用語、プレフィックス、コード、方言のチェック、MLCommonsバリデータの実行、mlcroissantによるレコードの読み取り(ファイルの最初の数行、全ダウンロードではない)、およびカバレッジの報告 |
ワークフロー
-
調査。 croissantの隣に
semantics_answers.jsonがあれば、最初にそれを読みます。ナレッジベースのメンテナーからの以前の質問への回答が含まれています(下記「メンテナー回答」を参照)。それらの質問を再度尋ねないでください。apply_plan.pyとcheck.pyは回答を自動的に計画に適用します。次にinventory.py CROISSANT。ナレッジベース(名前、説明、croissant内のURL)と、レコードセットがレイアウト全体にどのように分散しているかに注目してください。大規模なナレッジベースには数百のレイアウトがあります。リストの先頭から作業してください。ナレッジベース自体のinfores IDを今すぐ見つけてください(
vocab.py infores NAME; 完全な名前、頭字語、URLを試す)、それを計画のinforesとして設定します。これは、これらのファイルが属するリソースを識別し、グラフビルダーはそれらから読み取られるすべてのソースとしてそれを引用します。これがないと、変換段階はナレッジベースをまったく構築しません。複数のエントリが一致する場合は、これらのファイルを公開するリソースのものを選択し、再配布するサービスは選択しないでください(infores:reactome、infores:automat-reactomeではありません)。check.pyはこれを計画の残りの部分と比較します。単一のアグリゲーターまたはprovided_by定数もナレッジベースに名前を付け(HCOPのオーソログはinfores:hgncによってアグリゲートされます)、不一致は解決すべき警告です。どれも一致しない場合は、新しいものを提案します:
infores:とナレッジベースの短い名前を小文字でダッシュで結合したもの(infores:bioplex、infores:expression-atlas)、計画に"infores_proposed": trueを設定します。次に、vocab.py infores-entry CROISSANT --id infores:NAMEでカタログエントリを書き込み、ドキュメンテーションで明確な場合は--knowledge-levelと--agent-typeを追加し、それをnotes.mdに登録するInfores IDという見出しの下に、先頭近くに配置します。そこに、ユーザーがinforesレジストリへのプルリクエストで登録する必要があること(コマンドはどこに送信するかを出力します)、およびIDはレビュー中に変更される可能性があることを記載します。check.pyは、登録されるまで提案されたIDに対して警告を保持します。それを説明して回避しないでください。 -
実行するレイアウトを選択します。 ほとんどのレコードセットとコアコンテンツ(アソシエーションと主要なエンティティテーブル)をカバーするレイアウトを目指します。通常は上位5〜15、または残りのレイアウトがマイナー(READMEのようなファイル、ログ、リリースごとのカウント)になるまでです。小さなレイアウトが多数ある場合(
inventory.pyがそう言うでしょう)、レコードセットはおそらくコアカラムを共有しています。inventory.py --common-columnsを使用し、match.has_columnsでそれらのカラムを一度計画してください。省略するものはすべて、理由とともに計画のskippedリストに入れてください。多くのレイアウトをうまく処理するよりも、少数のレイアウトをうまく処理する方が良いです。 -
各レイアウトについて、決定する前にデータを確認します。
inventory.py CROISSANT --layout IDでカラム、説明、ファイル名を確認します。MIXEDとマークされたカラムは、異なるレコードセットで異なるアトミック型を持ちます(パイプラインはファイルごとに推論します)。データからその型を決定し、atomicを設定します。- テーブルの場合、
dialects.py detect CROISSANT --layout IDは、既知の形式の中でファイルがどのように書かれているか(コメント行、ヘッダーまたはなし、区切り文字)を見つけます。よく知られた形式(VCF、GAF、MITAB)には公開された仕様があります。形式を再発見するのではなく、それらに依存してください。何も適合しない場合は、インラインで方言を記述します(reference/dialects.md)。次に、--dialect NAMEを使用してサンプリングします。これにより、推測された方法ではなく、形式が指定する方法で行が読み取られます。 sample.py CROISSANT --layout IDで実際の値を確認します。レイアウトの3つのファイル(名前が最新のように見えるもの、最大のもの、最小のもの)を読み取ります。これは、1つのファイル(多くの場合、古いスナップショットまたはフィルタリングされたサブセット)が値を隠す可能性があるためです(N/Aプレースホルダー、追加のコード値、その他のIDタイプ)。--files Nはより多くのファイルをサンプリングします;--record-set IDは1つの特定のファイルをサンプリングします。サンプリングが失敗した場合(巨大なファイル、アーカイブ、ファイルセット)、計画のbasisにその旨を記載し、信頼度を下げます。- コードカラム(タイプ、証拠、関係、ソース)の場合、サンプルでは稀な値を見逃します。
sample.py CROISSANT --record-set ID --profile COL1,COL2はファイル全体を読み取り、個別の値ごとにカウントします;--record-setを繰り返して複数のファイルを追加します。サンプルではなく、プロファイルからマッピングしてください。 - ナレッジベースのサーバーに優しくしてください。 ナレッジベースごとに、一度に1つのサンプリングまたはチェックコマンドを実行し、並列に実行しないでください。ホストはボットチャレンジでバーストをブロックし、その後、後続のすべてのリクエストが失敗します。スクリプトは独自のリクエストを調整し、ダウンロードをキャッシュします(
~/.cache/croissant-semantics/downloads内;--refreshで再ダウンロード)。そのため、再実行は安価です(より大きな--max-mbの下でキャッシュされたコピーがより小さなものにサービスを提供します)。スクリプトがボットチャレンジまたはHTTP 403を報告した場合、そのホストのサンプリングを停止し、それを回避しようとせず、notes.mdにどのチェックが実行できなかったかを記載してください。スクリプトはその後、実行全体でそのホストを1時間拒否し、キャッシュされたファイルから動作します。 - スプレッドシート(xlsxおよびレガシーxls)、SQLiteデータベース、parquetファイルもサンプリングおよびプロファイリングされます。シートまたはテーブルは、レコードセットの名前がで終わるものです(「file.xlsx — Sheet1」、「file.xlsx: Sheet1」)。サンプリングは、判別できない場合、推測するのではなく失敗します。それらは全体が読み取られるため、必要に応じて
--max-mbを上げてください(check.pyでも同様)。mlcroissantはスプレッドシートやデータベースを読み取ることができないため、それらのレコードはロードされません。 - XML、RDF(Turtle、RDF/XML、OWL)、FASTA、およびその他のテーブルではないファイルはサンプリングできません。スクリプトはそのように言います。レイアウトが重要な場合は、
OUT/work/内の小さなスクリプトでそのIDをチェックし(RDFの場合はuv run --with rdflib;xml.etree.ElementTree.iterparseでXMLをストリーム)、notes.mdに方法を記載してください。それらのフィールドには通常extractがないため、どのツールも読み取ることができません。報告すべきジェネレーターの問題です。 --layoutを指定した--profileは、--record-setで各ファイルを指定する代わりに、レイアウトの--filesレコードセット(デフォルト3、またはall)をプロファイリングします。--prefixesは、すべてのプロファイリングされたカラムまたはリストされたカラムのみ(--prefixes COL1,COL2)について、各値のプレフィックスまたはタグをカウントします;--by COLは別のカラムに対してクロス集計します(各コードがどのオブジェクトタイプと共に発生するか);--split SEPはリストセルのアイテムをカウントします;--per-fileは各レコードセットを個別にプロファイリングします(IDがファイルごとに一意であることを確認するため);--stop-mb Nは各ファイルをN MB後に停止します(数十GBのファイルの場合、カウントは先頭のみをカバーします。種やIDでソートされたファイルでは、1つのグループのみになる可能性があるため、そのように記載してください)。- 主要なレイアウトのIDカラムをプロファイリングする(
--profile COL --shapes)信頼する前に: データチェックは数ファイルの最初の数行を読み取るため、後の行にIDがない、または別のIDファミリーが含まれているカラムはそれを通過します。いくつかのナレッジベースでは、すべてIDを持つ数百行の後に、20〜30%の行にIDがありませんでした。 - 多くのレイアウトをカバーする
match.has_columnsエントリは、check.pyによってそのファイルのほんの一部のみがサンプリングされます。それを信頼する前に、そのスパンが異なるレイアウトをサンプリングしてください(--record-set-name、--files)。 - スクリプトはオペレーティングシステムの証明書ストアを使用します。それでもダウンロードが証明書エラーで失敗する場合は、出力とともにそれを報告してください。検証をオフにしないでください。
- ドキュメンテーションがボットチェック(「あなたは人間ですか」の確認、CloudflareまたはALTCHAチャレンジ)の背後にある場合、それを回避しようとせず、データと名前から計画し、ドキュメンテーションのみが確認できる意味については信頼度を
mediumに上限設定してください。croissantの出典情報は、後にチェックの背後に置かれたページを引用する場合があります。読めたものだけを引用してください。 - 巨大なファイルでは、最初の行が代表的でない場合があります(CTDの3 GBの
genes_diseasesは、数千の推論された行で始まります)。全体をストリーミングする代わりに、同じレイアウトのより小さなファイル(キュレーションされたサブセット)をプロファイリングしてください。 - 名前でレコードセットを選択するには、
--record-set-name REGEXを使用します(--layoutの代わりに)。シェルで--record-set引数のリストを構築する必要はありません(zshは変数を単語に分割しません)。--per-fileは、レイアウトのファイルが異なる場合(ファイルごとに1つのID種類)、サンプリングされた各ファイルを個別に表示します。 - データチェックは数ファイルの最初の数行を読み取ります。カラムの後の行は異なる場合があります(200個のIRIの後のブランクノード、稀なコード):
--profileでID形式とコードを確認してください。これはファイル全体を読み取ります。 inventory.pyは、データと一緒に配布されるドキュメンテーションファイル(zip内のREADME.pdf、データ辞書)をレイアウトの後に一覧表示します。関連するものを読んでください:sample.py CROISSANT --dump FILEはファイルをテキストとして出力します;--member NAMEはアーカイブのメンバー(zipは全体が読み取られるため、大きなzipの場合は--max-mbを上げてください)(名前が間違っている場合はzipのメンバーを一覧表示します);--sheet NAMEはスプレッドシートのシートです。sample.pyは、宣言された型が値に適合しないカラム(27152464|29518214を保持するsc:Integerカラム)と、行がヘッダーより幅が広いまたは狭いファイルにフラグを立てます。両方とも通常はパイプラインの問題です。atomicで型を修正し、報告してください。- スクリプトがソースを読み取れない場合、ファイルを自分で取得し(一度に1つ、
OUT/work/内)、--url-map OLD=file:///abs/path/でスクリプトにそれらをポイントして、独自のプロファイラを作成する代わりにスクリプトのチェックが引き続き実行されるようにします。ダウンロードはキャッシュされ、~/.cache/croissant-semantics/downloads/index.tsvは各キャッシュされたファイルをそのURLにマッピングします。 - レイアウトの「カラム名」が実際にはデータである場合(ヘッダー行がないため、パイプラインが最初のデータ行を名前とみなし、すべてのファイルが独自のレイアウトになった)、それをスキップし、
notes.mdにパイプライン問題として報告してください。 - データURLがなくなった場合(HTTP 404)、ナレッジベースはおそらく新しいリリースに移行しています。そのダウンロードページから現在のURLを見つけ、
--url-map OLD=NEWをsample.pyとcheck.pyに渡します(例:--url-map 202607=202610)。リリース以上に変更があった場合(別のパスまたはファイル名)、ファイルごとに1つの--url-map OLD_URL=NEW_URLで完全なURLをマッピングします。URL自体に=が含まれている場合(クエリ文字列)、OLD=>NEWと記述します。notes.mdにその旨を記載してください。これもパイプライン問題です。Croissantがテーブルを記述している場所でJSONを返すSPARQLエンドポイントURLは、通常、&format=csv(またはtext/csv)をマッピングする必要があります。 - アーカイブ: zipおよびtarアーカイブのメンバーがサンプリングされます。zipは全体がダウンロードされます(
--max-mbまで); tarはメンバーが見つかるまでストリーミングされるため、巨大なtarの奥深くにあるメンバーは--max-mbを超える可能性があります。一度失敗したアーカイブは再試行されず、サンプリングは繰り返し失敗した後に停止します。必要であれば、自分でOUT/work/にメンバーを抽出し、何をどのようにチェックしたかをnotes.mdに記録してください。 - データにログインまたはAPIキーが必要な場合(HTTP 401/403、またはcroissantの
conditionsOfAccessがそのように述べている場合)、資格情報を探さないでください。ドキュメンテーションとカラム名のみから計画してください:sourceはdocumentationまたはagent、confidenceは最大でもmedium、notes.mdにはデータに対して何もチェックされなかったことを記載します。 - 出荷されたデータ辞書を探してください。 KEGGやSTRINGなどの知識ベースは、それらのファイル形式を説明するPDF、Word文書、またはWebページをデータと一緒に同梱しています。
inventory.pyは、すべてのファイルスキーマ(TSV、CSV、TSV、Excel)の後に、同梱されたドキュメントをレイアウト占有の下に一覧表示します。最初に、--dump FILE(テキストファイル)または--sheet NAME(Excelシート)で読み取ります。スプレッドシートデータ辞書はサンプリングもプロファイリングもできませんが、手動で確認できます。(アーカイブリストについては、アーカイブメンバー名は末尾の若い数字でソートされます:members.2023.tsvはmembers.2024.tsvの前にあります。)
-
各レイアウトに対してセマンティクスを計画します。
reference/plan-format.mdが完全な形式を示します。各レイアウトに対して:- ファイル形式(方言)を記述するか、既知の形式の1つとして認識します。方言はどのように行が区切られ、コメントがマークされ、引用符が使用され、カラム名が指定されるかを定義します(またはファイルにヘッダーがない)。
inventory.pyは、カラム名がパイプラインによって発明された(column_01…column_99)か、真のヘッダーから取得されたかを示します。既知の形式の1つ(gaf、mitab、vcf)として認識できる場合は、profileでnameを設定するだけです。 - そのデータが何であるか(レイアウトの
nameはおそらくそれを伝えますが、sample.pyで確認してください):- 主にアソシエーションテーブル(タンパク質-タンパク質相互作用、遺伝子-疾患、化合物-ターゲット)で、各行がサブジェクトをオブジェクトに関連付けます。`
- ファイル形式(方言)を記述するか、既知の形式の1つとして認識します。方言はどのように行が区切られ、コメントがマークされ、引用符が使用され、カラム名が指定されるかを定義します(またはファイルにヘッダーがない)。