用過網頁版本 BLAST 的童鞋都會發現,提交的序列比對往往在幾分鐘,甚至幾十秒就可以得到比對的結果;而通過調用 API 卻要花費幾十分鐘或者更長的時間!這到底是為什麼呢?
NCBIWWW 基本用法
首先,我們來看一下提供了基於 API 在線比對的 Biopython 模塊。
Biopython 中的 BLAST 提供了 over the Internet 和 locally 兩種選擇:
Bio.Blast.NCBIWWW 主要是基於 NCBI BLAST API 用於在線比對Bio.Blast.Applications 模塊則是調用本地安裝好的 BLAST 程序以及資料庫執行比對。
在這裡我們來重點看一下 Bio.Blast.NCBIWWW 。Bio.Blast.NCBIWWW 模塊中主要是通過 qblast() 函數來調用 BLAST 的在線版本。它具有三個非可選參數:
第一個參數是用於搜索的 blast 程序,為小寫字符串。目前,qblast(biopython==1.7.4)僅適用於 blastn,blastp,blastx,tblast 和 tblastx。第二個參數指定要搜索的資料庫。關於這個選項,在 NCBI Guide to BLAST 上有詳細的描述。第三個參數是包含查詢序列的字符串。這可以是序列本身,也可以是 fasta 格式的序列,或者是諸如 GI 號之類的標識符。
qblast 函數還接受許多其他選項參數,這些參數基本上類似於我們可以在 BLAST 網頁上設置的不同參數。我們在這裡只重點介紹其中一些:
參數 url_base 是設置用於在 Internet 上運行 BLAST 的基本 URL。默認情況下,它連接到 NCBI(即 url_base='https://blast.ncbi.nlm.nih.gov/Blast.cgi'),但是可以使用它連接到雲端運行的 NCBI BLAST 實例。更多詳細信息請參閱 qblast 功能的文檔。qblast 函數可以返回各種格式的 BLAST 結果,您可以使用可選的format_type 關鍵字進行選擇:「HTML」,「Text」,"ASN.1」 或 "XML"。默認值為 「XML」,因為這是解析器期望的格式。參數 expect 用於設置期望值或 e-value 閾值。
有關可選的 BLAST 參數的更多信息,請參考 NCBI 自己的文檔或 Biopython 內置的文檔:
請注意,NCBI BLAST 網站上的默認設置與 qblast 上的默認設置不太相同。如果獲得不同的結果,則需要檢查參數(例如,e-value 值和 gap 值)。
例如,如果您要使用 BLASTN 在核苷酸資料庫(nt)中搜索核苷酸序列,並且知道查詢序列的 GI 號,則可以使用:
另外,如果我們的查詢序列已經存在於 FASTA 格式的文件中,則只需打開文件並以字符串形式讀取此記錄,然後將其用作查詢參數:
我們還可以將 FASTA 文件作為 SeqRecord 對象進行讀取,然後僅提供序列本身進行比對:
僅提供序列意味著 BLAST 將自動為您的序列分配一個標識符。您可能更喜歡使用 SeqRecord 對象的 format 方法來製作 FASTA 字符串(其中將包含現有標識符):
無論給 qblast() 函數提供什麼參數,都應在 handle 對象(默認為 XML 格式)中返回結果。下一步是將 XML 輸出解析為表示搜索結果的 Python 對象,但是您可能想先保存輸出文件的本地副本。在調試從 BLAST 結果中提取信息的代碼時,我發現這特別有用(因為重新運行在線搜索速度很慢,並且浪費了 NCBI 計算機時間)。
我們需要小心一點,因為我們只能使用 result_handle.read() 讀取一次 BLAST 輸出——再次調用 result_handle.read() 會返回一個空字符串。
完成上面的操作後,結果將保存在文件 my_blast.xml 中,並且原始句柄已提取了所有數據(因此我們將其關閉了)。但是,BLAST 解析器的解析功能採用了類似於文件句柄的對象,因此我們可以打開保存的文件進行輸入:
現在我們已經將 BLAST 結果重新放回了句柄中,下一步,如果我們準備對它們進行處理,我們可以參考 Biopython 中 Parsing BLAST output 部分的內容,這裡不再說明。
NCBIWWW 實現
在了解 NCBIWWW 的實現前,我們先來看一下 NCBI BLAST 對於 API 使用的一些說明:
NCBI BLAST 伺服器是共享資源。為了確保整個社區都能使用該服務,他們可能會限制某些高流量用戶的搜索。他們會將在 24 小時內提交 100 次以上搜索的用戶的搜索移到較慢的隊列中,或者在極端情況下將阻止請求。 NCBI BLAST 優先考慮互動的用戶,通過網絡瀏覽器的 NCBI 網頁的交互式用戶不會遇到以上的問題。
對於 API 的使用準則:
與伺服器聯繫的頻率不要超過每 10 秒一次。不要輪詢每一個 RID(Request ID) 多於一分鐘一次。使用 URL 參數電子郵件和工具,以便 NCBI 在出現問題時可以與您聯繫。如果將提交超過 50 個搜索,則在周末或東部時間東部時間晚上 9 點至凌晨 5 點之間運行腳本。
我們再來看一下 NCBIWWW 在源碼層面的處理:
可以看到 NCBIWWW 從 20 秒的延遲開始,然後開始每隔一分鐘執行一次 request 輪詢,直至任務完成或者任務出現異常。
所以,總的來說,NCBI BLAST API 的使用準則,加上 NCBI BLAST 對用戶請求的任務隊列處理,甚至 NCBI BLAST 伺服器共享資源的限制,以及總用戶請求數,這些都可能成為 NCBIWWW.qblast() 異常耗時的原因,這其中還不算個人伺服器的網絡影響。綜上種種原因,如果考慮使用 NCBIWWW.qblast() 執行頻繁的序列在線批處理,或許不是一個好的解決方案。
最後,基於 Python 的 NCBI BLAST 在線批處理,如果你有更好的方法,歡迎留言交流。