用過網(wǎng)頁版本 BLAST 的童鞋都會發(fā)現(xiàn)谤牡,提交的序列比對往往在幾分鐘副硅,甚至幾十秒就可以得到比對的結果;而通過調(diào)用 API 卻要花費幾十分鐘或者更長的時間翅萤!這到底是為什么呢恐疲?
NCBIWWW 基本用法
首先,我們來看一下提供了基于 API 在線比對的 Biopython
模塊。
Biopython
中的 BLAST 提供了 over the Internet 和 locally 兩種選擇:Bio.Blast.NCBIWWW
主要是基于 NCBI BLAST API 用于在線比對培己;Bio.Blast.Applications
模塊則是調(diào)用本地安裝好的 BLAST 程序以及數(shù)據(jù)庫執(zhí)行比對碳蛋。在這里我們來重點看一下 Bio.Blast.NCBIWWW
。
Bio.Blast.NCBIWWW
模塊中主要是通過 qblast()
函數(shù)來調(diào)用 BLAST 的在線版本省咨。它具有三個非可選參數(shù):
- 第一個參數(shù)是用于搜索的 blast 程序肃弟,為小寫字符串。目前零蓉,
qblast
(biopython==1.7.4)僅適用于 blastn愕乎,blastp,blastx壁公,tblast 和 tblastx感论。 - 第二個參數(shù)指定要搜索的數(shù)據(jù)庫。關于這個選項紊册,在 NCBI Guide to BLAST 上有詳細的描述比肄。
- 第三個參數(shù)是包含查詢序列的字符串。這可以是序列本身囊陡,也可以是 fasta 格式的序列芳绩,或者是諸如 GI 號之類的標識符。
qblast
函數(shù)還接受許多其他選項參數(shù)撞反,這些參數(shù)基本上類似于我們可以在 BLAST 網(wǎng)頁上設置的不同參數(shù)妥色。我們在這里只重點介紹其中一些:
- 參數(shù)
url_base
是設置用于在 Internet 上運行 BLAST 的基本 URL。默認情況下遏片,它連接到 NCBI(即 url_base='https://blast.ncbi.nlm.nih.gov/Blast.cgi')嘹害,但是可以使用它連接到云端運行的 NCBI BLAST 實例。更多詳細信息請參閱 qblast 功能的文檔吮便。 - qblast 函數(shù)可以返回各種格式的 BLAST 結果笔呀,您可以使用可選的
format_type
關鍵字進行選擇:“HTML”,“Text”髓需,"ASN.1” 或 "XML"许师。 默認值為 “XML”,因為這是解析器期望的格式僚匆。 - 參數(shù)
expect
用于設置期望值或 e-value 閾值微渠。
有關可選的 BLAST 參數(shù)的更多信息,請參考 NCBI 自己的文檔或 Biopython 內(nèi)置的文檔:
>>> from Bio.Blast import NCBIWWW
>>> help(NCBIWWW.qblast)
請注意咧擂,NCBI BLAST 網(wǎng)站上的默認設置與 qblast 上的默認設置不太相同逞盆。如果獲得不同的結果,則需要檢查參數(shù)(例如屋确,e-value
值和 gap
值)纳击。
例如续扔,如果您要使用 BLASTN 在核苷酸數(shù)據(jù)庫(nt)中搜索核苷酸序列,并且知道查詢序列的 GI 號焕数,則可以使用:
>>> from Bio.Blast import NCBIWWW
>>> result_handle = NCBIWWW.qblast("blastn", "nt", "8332116")
另外纱昧,如果我們的查詢序列已經(jīng)存在于 FASTA 格式的文件中,則只需打開文件并以字符串形式讀取此記錄堡赔,然后將其用作查詢參數(shù):
>>> from Bio.Blast import NCBIWWW
>>> fasta_string = open("m_cold.fasta").read()
>>> result_handle = NCBIWWW.qblast("blastn", "nt", fasta_string)
我們還可以將 FASTA 文件作為 SeqRecord
對象進行讀取识脆,然后僅提供序列本身進行比對:
>>> from Bio.Blast import NCBIWWW
>>> from Bio import SeqIO
>>> record = SeqIO.read("m_cold.fasta", format="fasta")
>>> result_handle = NCBIWWW.qblast("blastn", "nt", record.seq)
僅提供序列意味著 BLAST 將自動為您的序列分配一個標識符。您可能更喜歡使用 SeqRecord
對象的 format
方法來制作 FASTA 字符串(其中將包含現(xiàn)有標識符):
>>> from Bio.Blast import NCBIWWW
>>> from Bio import SeqIO
>>> record = SeqIO.read("m_cold.fasta", format="fasta")
>>> result_handle = NCBIWWW.qblast("blastn", "nt", record.format("fasta"))
無論給 qblast()
函數(shù)提供什么參數(shù)善已,都應在 handle
對象(默認為 XML 格式)中返回結果灼捂。下一步是將 XML 輸出解析為表示搜索結果的 Python 對象,但是您可能想先保存輸出文件的本地副本换团。在調(diào)試從 BLAST 結果中提取信息的代碼時悉稠,我發(fā)現(xiàn)這特別有用(因為重新運行在線搜索速度很慢,并且浪費了 NCBI 計算機時間)艘包。
我們需要小心一點的猛,因為我們只能使用 result_handle.read()
讀取一次 BLAST 輸出——再次調(diào)用 result_handle.read()
會返回一個空字符串。
>>> with open("my_blast.xml", "w") as out_handle:
... out_handle.write(result_handle.read())
...
>>> result_handle.close()
完成上面的操作后想虎,結果將保存在文件 my_blast.xml 中卦尊,并且原始句柄已提取了所有數(shù)據(jù)(因此我們將其關閉了)。 但是舌厨,BLAST 解析器的解析功能采用了類似于文件句柄的對象岂却,因此我們可以打開保存的文件進行輸入:
>>> result_handle = open("my_blast.xml")
現(xiàn)在我們已經(jīng)將 BLAST 結果重新放回了句柄中,下一步裙椭,如果我們準備對它們進行處理躏哩,我們可以參考 Biopython 中 Parsing BLAST output 部分的內(nèi)容,這里不再說明骇陈。
NCBIWWW 實現(xiàn)
在了解 NCBIWWW 的實現(xiàn)前震庭,我們先來看一下 NCBI BLAST 對于 API 使用的一些說明:
- NCBI BLAST 服務器是共享資源瑰抵。為了確保整個社區(qū)都能使用該服務你雌,他們可能會限制某些高流量用戶的搜索。
- 他們會將在 24 小時內(nèi)提交 100 次以上搜索的用戶的搜索移到較慢的隊列中二汛,或者在極端情況下將阻止請求婿崭。
- NCBI BLAST 優(yōu)先考慮互動的用戶,通過網(wǎng)絡瀏覽器的 NCBI 網(wǎng)頁的交互式用戶不會遇到以上的問題肴颊。
對于 API 的使用準則:
- 與服務器聯(lián)系的頻率不要超過每 10 秒一次氓栈。
- 不要輪詢每一個 RID(Request ID) 多于一分鐘一次。
- 使用 URL 參數(shù)電子郵件和工具婿着,以便 NCBI 在出現(xiàn)問題時可以與您聯(lián)系授瘦。
- 如果將提交超過 50 個搜索醋界,則在周末或東部時間東部時間晚上 9 點至凌晨 5 點之間運行腳本。
我們再來看一下 NCBIWWW 在源碼層面的處理:
可以看到 NCBIWWW 從 20秒的延遲開始提完,然后開始每隔一分鐘執(zhí)行一次 request 輪詢形纺,直至任務完成或者任務出現(xiàn)異常。
所以徒欣,總的來說逐样,NCBI BLAST API 的使用準則,加上 NCBI BLAST 對用戶請求的任務隊列處理打肝,甚至 NCBI BLAST 服務器共享資源的限制脂新,以及總用戶請求數(shù),這些都可能成為 NCBIWWW.qblast()
異常耗時的原因粗梭,這其中還不算個人服務器的網(wǎng)絡影響争便。綜上種種原因,如果考慮使用 NCBIWWW.qblast()
執(zhí)行頻繁的序列在線批處理断医,或許不是一個好的解決方案始花。
最后,基于 Python 的 NCBI BLAST 在線批處理孩锡,如果你有更好的方法酷宵,歡迎留言交流。