為 croissant 添加語意
一個 RoboCroissant 檔案說明了知識庫包含哪些檔案以及它們包含哪些欄位。此技能添加資料含義的資訊:哪些欄位共同描述了一個基因或疾病、一行資料斷言了什麼、一個欄位的 ID 使用了哪個標識符前綴、以及代碼代表什麼。它會將這些內容寫入一個新的 croissant,使用 Croissant 1.1 結構,並記錄做出每個陳述的原因。
您將生成一個計劃(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] | 列出佈局(不同的欄位集),從最大開始;描述一個佈局的欄位、記錄集和檔案;列出大多數記錄集共有的欄位 |
sample.py CROISSANT --layout ID | 從三個該佈局的檔案中讀取實際資料行;顯示每個欄位的範例值及其形狀(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 中的網址)以及記錄集在不同佈局中的分佈情況。大型知識庫可能有數百個佈局;從列表頂部開始處理。立即查找知識庫自身的 infores ID(
vocab.py infores NAME;嘗試其全名、縮寫和網址),並將其設定為計劃的infores。它命名了這些檔案所屬的資源,並且圖譜建構器會將其引用為從這些檔案中讀取的所有內容的來源:沒有它,轉換階段根本無法建構知識庫。當有多個匹配項時,請選擇發布這些檔案的資源所對應的 ID,而不是重新提供該資源的服務(infores:reactome,而不是infores:automat-reactome)。check.py會將其與計劃其餘部分所說的內容進行比較:單一的aggregator或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的欄位在不同的記錄集中具有不同的原子類型(pipeline 會針對每個檔案進行推斷);根據資料決定其類型並設定atomic。 - 對於表格,使用
dialects.py detect CROISSANT --layout ID在已知格式中找出檔案的書寫方式(註解行、是否有標題行、分隔符)。眾所周知的格式(VCF, GAF, MITAB)有已發布的規範;請依賴它們,而不是重新發現格式。如果沒有合適的,請內聯描述該方言(reference/dialects.md)。然後使用--dialect NAME進行取樣,以便按照格式指定的方式讀取行,而不是猜測。 - 使用
sample.py CROISSANT --layout ID獲取實際值。它會讀取該佈局的三個檔案(按名稱看最新的、最大的、最小的),因為一個檔案——通常是舊的快照或過濾後的子集——可能隱藏某些值(N/A佔位符、額外的代碼值、其他 ID 類型)。使用--files N可以取樣更多檔案;使用--record-set ID可以取樣一個特定的檔案。如果取樣失敗(檔案過大、存檔、檔案集),請在計劃的basis中說明,並降低置信度。 - 對於代碼欄位(類型、證據、關係、來源),取樣會遺漏罕見的值。使用
sample.py CROISSANT --record-set ID --profile COL1,COL2讀取整個檔案並計數每個不同的值;重複--record-set可以添加多個檔案。根據輪廓資料(profile)而不是取樣進行映射。 - 善待知識庫的伺服器。 一次只對一個知識庫運行一個取樣或檢查命令,切勿並行運行多個:主機會用機器人驗證挑戰來阻止突發請求,然後之後的每個請求都會失敗。腳本會控制自身的請求速率並快取下載(在
~/.cache/croissant-semantics/downloads目錄中;使用--refresh重新下載),因此重新運行的成本很低(在較大--max-mb下快取的副本可以為較小請求提供服務)。如果腳本報告機器人挑戰或 HTTP 403 錯誤,請停止取樣該主機,不要嘗試繞過它,並在notes.md中說明哪些檢查無法運行。然後腳本會在一小時內拒絕該主機(跨運行),並使用快取的檔案進行工作。 - 電子表格(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,因此沒有工具可以讀取它們:這是一個需要報告的 pipeline 問題。 --profile搭配--layout會分析該佈局的--files個記錄集(預設為 3 個,或all),而不是使用--record-set命名每個。--prefixes會計算每個值的前綴或標籤,適用於所有分析的欄位或僅列表中指定的欄位(--prefixes COL1,COL2);--by COL會針對另一個欄位進行交叉製表(每個代碼與哪些對象類型一起出現);--split SEP會計算列表儲存格中的項目數;--per-file會單獨分析每個記錄集(以檢查 ID 是否在檔案內唯一);--stop-mb N會將每個檔案的分析限制在前 N MB,適用於數 GB 的檔案(計數僅涵蓋開頭部分;在按物種或 ID 排序的檔案中,這可能只是一個組,因此請說明)。- 在信任主要佈局的 ID 欄位之前先對其進行分析(
--profile COL --shapes):資料檢查僅讀取少數幾個檔案的前幾行,因此一個後續行缺少 ID 或包含另一系列 ID 的欄位可能會通過檢查。有幾個知識庫在數百行都包含 ID 的行之後,有 20-30% 的行缺少 ID。 - 一個覆蓋許多佈局的
match.has_columns條目,check.py僅在其少數檔案上進行取樣。在信任它之前,請對其涵蓋的不同佈局進行取樣(使用--record-set-name、--files)。 - 腳本使用作業系統的證書儲存。如果下載仍然因證書錯誤而失敗,請連同輸出一起報告;請勿關閉驗證。
- 如果文件位於機器人驗證檢查之後("verify you are human",Cloudflare 或 ALTCHA 挑戰),請不要嘗試繞過它;僅根據資料和名稱進行規劃,並將置信度上限設為
medium,僅適用於只有文件才能確認的含義。croissant 的出處資訊可能引用了此後被置於驗證檢查之後的頁面:僅引用您能夠讀取的內容。 - 在一個巨大的檔案中,前幾行可能不具代表性(CTD 的 3 GB
genes_diseases檔案以數千個推斷行開頭)。請分析同一佈局的一個較小檔案(已策展的子集),而不是串流整個大檔案。 - 若要按名稱選擇記錄集,請使用
--record-set-name REGEX(而不是--layout),而不是在 shell 中構建--record-set參數列表(zsh 不會將變數拆分為單詞)。--per-file會單獨顯示每個取樣的檔案,適用於檔案不同的佈局(每個檔案一種 ID 類型)。 - 資料檢查會讀取少數檔案的前幾行。一個欄位的後續行可能不同(200 個 IRI 之後出現空白節點、罕見代碼):請使用
--profile(讀取整個檔案)來確認 ID 形式和代碼。 inventory.py會在佈局之後列出隨資料一起提供的文件檔案(zip 中的 README.pdf、資料字典)。請閱讀相關文件:sample.py CROISSANT --dump FILE將檔案列印為文字,--member NAME用於存檔中的一個成員(zip 會被完整讀取,因此對於大檔案請提高--max-mb)(當名稱錯誤時,它會列出 zip 的成員),--sheet NAME用於電子表格中的一個工作表。sample.py會標記宣告類型與值不匹配的欄位(持有27152464|29518214的sc:Integer欄位)以及行寬與標題行寬不同的檔案。兩者通常都是 pipeline 問題:使用atomic修正類型,並報告它們。- 當腳本無法讀取來源時,請自行獲取檔案(一次一個,放入
OUT/work/目錄),並使用--url-map OLD=file:///abs/path/將腳本指向它們,以便它們的檢查仍能運行,而不是編寫自己的分析器。下載會被快取,並且~/.cache/croissant-semantics/downloads/index.tsv會將每個快取的檔案映射到其 URL。 - 如果某個佈局的“欄位名稱”實際上是資料(沒有標題行,因此 pipeline 將第一行資料作為名稱,並且每個檔案都成為自己的佈局),請跳過它,並在
notes.md中將其報告為 pipeline 問題。 - 如果資料 URL 已失效(HTTP 404),則知識庫可能已遷移到較新版本。從其下載頁面找到當前的 URL,並將
--url-map OLD=NEW傳遞給sample.py和check.py(例如--url-map 202607=202610)。當更改的不僅僅是版本時(例如另一個路徑或檔案名稱),請映射完整的 URL,每個檔案一個--url-map OLD_URL=NEW_URL。當 URL 本身包含=(查詢字串)時,請寫成OLD=>NEW。在notes.md中說明;這也是一個 pipeline 問題。一個返回 JSON 的 SPARQL 端點 URL,當 croissant 將其描述為表格時,通常需要映射&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說明未對資料進行任何檢查。 - 尋找附帶的資料字典、README、documentation 檔案、物件模型圖表、模型卡片和 ER 圖* 它們比推測更可靠,並且可以為您節省大量取樣時間。使用
inventory.py CROISSANT --docs(或inventory.py列印末尾的部分)查找它們。查看 zip 和 tar 的成員以及--dump也可以。文件中的命名慣例(GRCh38, hg38)可以在沒有文件的情況下驗證——使用 sample 來確認。使用-R遞迴搜索/path/to/data/目錄——一些知識庫在其發布中捆綁了大量文件,但在其 croissant 中只列出了資料檔案。find和grep可以節省數小時的時間。在 notes.md 中寫下您發現的內容。 - 對於許多未連接起來的資料集(
/by-gene/,/by-variant/):如果佈局超過 100 個,則它們大多數是分開的,並且相同檔案出現在多個佈局中。在這種情況下,使用 match.includes 涵蓋它們,而不是單獨為每個佈局編寫一個條目。對具有三個以上佈局的庫進行分組,並確保同一個檔案不會被多次匹配。 - 如果知識庫沒有 infores,並且我們需要一個用於作者的條目:查找源代碼(GitHub, GitLab, Bitbucket)。使用
vocab.py infores --search NAME/REGEX和vocab.py search github:NAME REPO。對於一個新的 infores 條目,添加...
- 使用
計劃格式
計劃是一個 JSON 檔案,包含一個佈局列表。每個佈局包含...
維護者答案
當知識庫的維護者回答了一個先前計劃的問題時...
(其餘內容因篇幅截斷,但翻譯會遵循相同的原則和風格)