來自 OBO 檔案和 OLS4 的本體術語標籤
標註者可以搜尋 Cell Ontology、HPO、GO 或任何 OBO 本體,每次選擇都會連同術語 id、名稱、IRI 和版本一起儲存,可離線使用,也可通過 OLS4 使用。
v2.13.0 新增
在 radio、multiselect、span 或 image_annotation 標註方案上加一個 label_source 塊,就會多出一個針對某個本體的搜尋框。標註者輸入名稱、同義詞或 id 來選取術語,不必在固定的標籤列表裡翻找。每次選擇都會連同術語的 id、名稱、IRI 以及該術語所屬的本體版本一起儲存。生物審編人員用這項功能做基於 Cell Ontology 的細胞類型標註、基於人類表型本體(HPO)的表型標註和基於 MONDO 的疾病規範化,也用它為化學物質提及標註 ChEBI 術語、為切片上的組織區域標註 UBERON 術語、為基因產物標註 GO 術語。Potato 的一致性指標和匯出都讀取術語 id。一位標註者搜尋了 "B cell",另一位直接輸入了 id CL:0000236,兩人的答案儲存的是同一個 id,因此判為一致。
OBO 平面檔案格式是 OBO Foundry 本體釋出時使用的純文本格式。Potato 讀取 OBO 1.4。Ontology Lookup Service(OLS4)是 EMBL-EBI 面向生物醫學本體的搜尋服務和 API,機構也可以自行執行 OLS4 伺服器。
- 本地檔案: 設定
service: file時,Potato 在任務目錄內的 OBO 1.4 檔案中搜索。檔案來源可以離線使用。 - OLS4: 設定
service: ols4時,Potato 在 OLS4 伺服器上搜索。每次搜尋都會把輸入的文本傳送到該伺服器,除非標註方案設定了allow_network: true,否則 Potato 拒絕啟動。請求由 Potato 伺服器發出,標註者的瀏覽器只與 Potato 通訊。 - 儲存的記錄: 每次選擇都儲存為
{obo_id, label, iri, ontology_version}。Potato 的一致性指標比較的是obo_id。 - 匯出: 執行
python -m potato.export並加上--format ontology_terms,每個被選中的術語寫為一行。 - 無需額外安裝: Potato 用自帶的解析器讀取 OBO,OLS4 呼叫使用 Potato 本來就依賴的
requests包。
配置
下面的配置基於 Potato 示例中的合成樣例本體,設定了三個標註方案。第一個方案只通過搜尋框詢問一個主要細胞類型,第二個方案在搜尋框上方提供一個固定的 None 選項,第三個方案只用免疫細胞術語來標註文本片段:
annotation_task_name: "Cell types from an ontology"
task_dir: .
output_annotation_dir: annotation_output
data_files: [data/cell-descriptions.jsonl]
item_properties: {id_key: id, text_key: text}
user_config:
allow_all_users: true
annotation_schemes:
- annotation_type: radio
name: main_cell_type
description: "Which cell type does the description mainly talk about?"
labels: [] # search box only
label_requirement: {required: true}
label_source:
ontology: scl
service: file
file: ontologies/scl-sample.obo
- annotation_type: multiselect
name: other_cell_types
description: "Which other cell types are mentioned?"
labels: [None] # a fixed option above the search box
label_source:
ontology: scl
service: file
file: ontologies/scl-sample.obo
- annotation_type: span
name: immune_cell_mentions
description: "Highlight each immune cell mention and tag its type"
labels: []
label_source:
ontology: scl
service: file
file: ontologies/scl-sample.obo
root: SCL:0000001 # immune cell and its is_a descendants設定 labels: [] 或不寫 labels 鍵時,搜尋框是唯一的作答方式。給出一個列表時,固定標籤照常顯示,搜尋框位於固定標籤下方。固定標籤儲存為普通的標籤名,只有從搜尋中選取的術語才儲存為本體術語。由於第一個方案設定了 required,在標註者選取術語之前,Potato 會一直停用 Next。對於第三個方案,Potato 把搜尋範圍限定在 root 免疫細胞術語及其通過 is_a 關係向下的所有術語。神經元術語永遠不會出現在片段搜尋中。
Potato 不附帶任何本體檔案。請把所需的 .obo 版本下載到任務目錄,並與項目一起儲存。HPO 的釋出檔案是 http://purl.obolibrary.org/obo/hp.obo,Cell Ontology 的釋出檔案是 http://purl.obolibrary.org/obo/cl.obo。示例中的 scl-sample.obo 是一個虛構的本體,包含 19 個現行術語和 1 個已廢棄術語,字首為 SCL。這些 SCL id 不是 Cell Ontology 的 id。
對於影像標註方案,同樣的塊放在繪圖工具旁邊。下面這段區域性配置為上面的配置新增第四個方案:
- annotation_type: image_annotation
name: cells_in_image
description: "Box each cell and name its type"
tools: [bbox, polygon]
labels: []
label_source:
ontology: scl
service: file
file: ontologies/scl-sample.obo改為在 OLS4 中搜索
下面這段區域性配置把上面配置中的 annotation_schemes 替換為一個方案,在 EBI 的 OLS4 伺服器上搜索 Cell Ontology。ontology 的值是 OLS4 的本體 id,例如 cl、hp、go、mondo、chebi 或 uberon:
annotation_schemes:
- annotation_type: radio
name: cell_type
description: "Which cell type is described?"
labels: []
label_source:
ontology: cl
service: ols4
allow_network: true # required for ols4
root: CL:0000000 # optional, sent to OLS4 as childrenOf
timeout_s: 5要搜尋自託管的 OLS4 伺服器,請設定 base_url。allow_network 鍵是有意要求顯式開啟的。如果研究的搜尋文本必須留在你自己的網路內,請使用 service: file。OLS4 塊缺少 allow_network: true 時,Potato 拒絕啟動。
選項
label_source 接受的全部鍵:
| 鍵 | 服務 | 預設值 | 含義 |
|---|---|---|---|
ontology | 兩者 | 必填 | 簡短的本體名稱(cl、hp)。該名稱顯示在搜尋框的標籤中;對於 OLS4,名稱轉為小寫後作為本體 id 傳送給伺服器 |
service | 兩者 | 必填 | file 或 ols4 |
file | file | 必填 | OBO 1.4 檔案的路徑,相對於 task_dir,且必須位於 task_dir 內。URL 會被拒絕,因為 Potato 不下載本體檔案 |
max_file_mb | file | 300 | 超過該大小(以兆位元組計)的檔案在啟動時被拒絕 |
root | 兩者 | 無 | 一個術語 id,例如 CL:0000000。只提供該術語及其通過 is_a 關係向下的術語 |
max_results | 兩者 | 20 | 每次搜尋顯示的匹配數,取 1 到 100 之間的整數 |
allow_network | ols4 | false | 使用 service: ols4 時必須為 true |
base_url | ols4 | https://www.ebi.ac.uk/ols4/api | OLS4 API 根地址 |
timeout_s | ols4 | 5 | 等待 OLS4 的秒數,取 0.5 到 30 |
出現以下任一情況時,伺服器和 python -m potato.validate_cli 都會拒絕配置,並指出出錯的鍵:
label_source放在了radio、multiselect、span或image_annotation以外的方案類型上;service不是file或ols4,或者某個鍵屬於另一種服務(例如base_url與file同用);- 存在未知的鍵;
- 檔案缺失、位於
task_dir之外、大於max_file_mb、是 OWL 檔案,或不含任何術語; root不是檔案中的術語,或已被標為廢棄;- 設定了
service: ols4卻沒有allow_network: true。
OBO 檔案解析
Potato 讀取 data-version、ontology 和 default-namespace 這幾個檔案頭標籤。在每個 [Term] 段中,解析器讀取 id、name、namespace、synonym、def、is_a、alt_id 和 is_obsolete,以及較舊檔案中出現的 OBO 1.0 同義詞標籤,例如 exact_synonym。[Typedef] 段會被跳過,relationship: 和 intersection_of: 行不算作邊。因此 Potato 只根據 is_a 構建 root 子樹。例如,UBERON 的子樹包含根術語的子類,但不包含僅通過 part_of 與根術語相連的結構。
儲存的 ontology_version 是檔案的 data-version 頭,例如樣例中的 scl/releases/2026-10-01。沒有該檔案頭的檔案,版本記為 sha256: 加上檔案雜湊的前 12 位十六進位制數字。檔案只解析一次並儲存在記憶體中。檔案的大小或修改時間發生變化時,Potato 會重新解析。把新版本複製覆蓋舊檔案後,下一次搜尋即生效,無需重啟。
已廢棄的術語不會出現在搜尋結果和任何子樹中,Potato 也不會沿 replaced_by 標籤跳轉到更新的術語。搜尋某個 alt_id 會找到主術語,Potato 儲存的是主 id。OWL 檔案會被拒絕並給出提示。大多數 OBO Foundry 本體在 .owl 檔案之外還會發布 .obo 版本。請下載 .obo 版本,或用 ROBOT 轉換 OWL 檔案:
robot convert --input cl.owl --output cl.obo對於 NCBITaxon 這樣的大型本體,請使用精簡版(slim)或子集檔案、調高 max_file_mb,或通過 OLS4 搜尋該本體。
搜尋和選取術語
標註者至少輸入名稱、同義詞或術語 id 的兩個字元。檔案搜尋的排序依次是:術語 id(CL:0000236、CL_0000236、某個 alt_id 或完整 PURL)排在最前,然後是名稱完全匹配、名稱以輸入文本開頭、名稱中各個詞分別以輸入的各個詞開頭。同義詞按同樣三種方式匹配,其後是名稱中任意位置出現輸入文本,最後是同義詞中任意位置出現輸入文本。所有同義詞範圍(EXACT、BROAD、NARROW 和 RELATED)都參與匹配,通過同義詞找到的結果會在術語名稱下方顯示該同義詞。每條結果還顯示術語 id 和定義的前 240 個字元。在樣例本體中,輸入 white blood 會通過同義詞 "white blood cell" 找到 leukocyte,輸入 SCL:0000099 會通過該術語的 alt_id 找到 T cell。
匹配的術語多於 max_results 時,一行狀態資訊會給出已顯示的數量和總數,並提示標註者繼續輸入。搜尋框下方有一行說明來源:檔案來源顯示本體和檔案的版本,OLS4 來源顯示本體名稱加 "via OLS4"。
- 鍵盤: 上下方向鍵在匹配項之間移動,Enter 選取高亮的匹配項,Escape 關閉列表,再按一次 Escape 清空搜尋框。點選或輕觸匹配項同樣可以選取,每個匹配項的觸控區域至少 44 畫素高。
radio: 選取的術語顯示為一個已選中的選項,選取另一個術語會替換前一個。multiselect: 每個選取的術語顯示為一個已勾選的核取方塊,取消勾選即移除該術語。span: 選取的術語成為當前的片段標籤,標註者隨後高亮文本。高亮上方的標籤塊顯示術語名稱。image_annotation: 選取的術語成為一個標籤按鈕和當前標籤,標註者隨後開始繪製。影像上已使用過的術語會在頁面載入時顯示為按鈕。
Pocket Mode 不顯示搜尋框。因此,含有 label_source 方案的任務總是使用常規標註頁面。常規頁面在手機上同樣可用。
網路訪問與 OLS4 快取
對於 service: file 方案,Potato 在任何時候都不發出網路請求。.obo 檔案放進任務目錄後,檔案來源可以在氣隙部署中執行。搜尋在 Potato 伺服器上針對解析後的檔案進行。沒有 allow_network: true 的 OLS4 方案無法訪問網路,因為伺服器會拒絕以該配置啟動,並建議改用本地檔案。
設定 service: ols4 和 allow_network: true 後,Potato 伺服器把每次搜尋連同 obsoletes=false 一起傳送給 OLS4,OLS4 隨即在結果中排除已廢棄的術語。搜尋結果在伺服器記憶體中快取六小時,最多 512 個不同的搜尋;本體的版本字串同樣快取六小時。瀏覽器可能在五分鐘內複用同一個結果。OLS4 返回的每個術語還會寫入 <output_annotation_dir>/ontology_cache/<ontology>-ols4-terms.json。重新載入後,Potato 從這個檔案讀取片段標籤塊和影像標籤按鈕上的術語名稱,匯出也讀取同一個檔案。
OLS4 響應緩慢或無法訪問時,搜尋框會顯示 "Search failed: OLS4 did not answer within 5 s." 或以 "Search failed: OLS4 request failed" 開頭的訊息,標註者仍可以回答固定標籤。過去六小時內回答過的搜尋由快取提供。已經選取的術語仍然儲存著,因為單選或多選答案儲存的是完整記錄,而片段和影像答案通過磁碟上的術語檔案解析。如果 Potato 無法從 OLS4 讀取本體的版本,選取會以空的 ontology_version 儲存,直到下一次版本查詢,最長六小時。對於必須在網路中斷期間照常執行的研究,請下載 .obo 檔案並切換到 service: file。
儲存的答案
選取的術語儲存為下面這樣的記錄:
{"obo_id": "SCL:0000005", "label": "CD4-positive T cell",
"iri": "http://purl.obolibrary.org/obo/SCL_0000005",
"ontology_version": "scl/releases/2026-10-01"}對於檔案來源,iri 是由 id 構建的 OBO PURL;對於 OLS4,iri 是 OLS4 返回的 IRI。單選或多選答案保留選取那一刻的 ontology_version。.obo 檔案被替換後,答案記錄的仍然是標註者搜尋時所用的版本。
| 方案 | 儲存方式 |
|---|---|
radio、multiselect | 每個術語一個標籤。標籤名是 obo_id,值是上面那條記錄的 JSON 字串 |
span | 片段的標籤(name)是 obo_id |
image_annotation | 每個形狀的 label 是 obo_id,位於常規的 _data JSON 中 |
片段和形狀只儲存 id。匯出時,service: file 從 .obo 檔案中查詢名稱、IRI 和版本,service: ols4 則從 ontology_cache 下的 OLS4 術語檔案中查詢。對於檔案模式下的片段和形狀,匯出寫入的是匯出時 .obo 檔案的版本。
匯出
ontology_terms 格式寫出 ontology_terms.csv 和 ontology_terms.jsonl,每個選取的術語一行:
python -m potato.export --config config.yaml --format ontology_terms --output out/以上面的配置為例,某位標註者在第一個條目上的 ontology_terms.csv 內容如下:
user_id,instance_id,schema,annotation_type,ontology,obo_id,label,iri,ontology_version,start,end,text,shape_index,shape_type,known
ana,cells_01,main_cell_type,radio,scl,SCL:0000005,CD4-positive T cell,http://purl.obolibrary.org/obo/SCL_0000005,scl/releases/2026-10-01,,,,,,true
ana,cells_01,other_cell_types,multiselect,scl,SCL:0000011,macrophage,http://purl.obolibrary.org/obo/SCL_0000011,scl/releases/2026-10-01,,,,,,true
ana,cells_01,immune_cell_mentions,span,scl,SCL:0000011,macrophage,http://purl.obolibrary.org/obo/SCL_0000011,scl/releases/2026-10-01,128,150,large phagocytic cells,,,truestart、end 和 text 列只對片段填寫,shape_index 和 shape_type 只對影像形狀填寫。當 id 不在當前檔案或 OLS4 術語檔案中時,known 列為 false。被新版本刪除或標為廢棄的術語會得到 false。匯出會列印一條警告,給出這類行的數量。同一方案上的固定標籤不會成為 ontology_terms 中的行。通用的 csv 匯出把單選或多選術語寫成名為 <schema>.<obo_id> 的列,列中是 JSON 記錄;片段和形狀則以 obo_id 作為標籤。其他格式見匯出格式。
一致性
Potato 的一致性指標比較的是 obo_id。radio 方案按名義標籤計分(百分比一致率、Cohen's kappa、Fleiss' kappa 和 Krippendorff's alpha),multiselect 方案按術語 id 集合的 Jaccard 重疊和 MASI 加權 alpha 計分,span 方案按片段位置和 obo_id 計分,image_annotation 方案按每個形狀的幾何形狀和術語 id 計分。兩位標註者選取同一個術語即判為一致,即使兩人的記錄中 ontology_version 不同。父術語和子術語算作不同的標籤,一致性計算不會沿本體層級給予部分得分。例如,T cell 和 CD4-positive T cell 計為不一致。如需考慮層級的比較,請匯出 ontology_terms,並根據同一個 .obo 版本,用 obo_id 列自行計算相應指標。
示例
python potato/flask_server.py start examples/classification/ontology-labels/config.yaml -p 8000該示例包含四段簡短的細胞描述、合成的 scl-sample.obo 本體,以及上面配置中的三個方案。
延伸閱讀
- 生命科學 - 用 Potato 做生物審編和生命科學標註
- 醫療健康與臨床 - 用 Potato 做臨床和生物醫學標註
- 實體連結 - 把提及連結到知識庫條目,片段標籤仍是固定類別
- 單選與多選 - 接受
label_source的單選和多選標註方案 - 匯出格式 - Potato 的匯出格式和匯出命令
實現細節請參閱源文件。