为什么 Biopython 的在线 BLAST 这么慢?

用过网页版本 BLAST 的童鞋都会发现,提交的序列比对往往在几分钟,甚至几十秒就可以得到比对的结果;而通过调用 API 却要花费几十分钟或者更长的时间!这到底是为什么呢?

ncbi_blast.png
ncbi_blast.png

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 内置的文档:

>>> from Bio.Blast import NCBIWWW
>>> help(NCBIWWW.qblast)

请注意,NCBI BLAST 网站上的默认设置与 qblast 上的默认设置不太相同。如果获得不同的结果,则需要检查参数(例如,e-value 值和 gap 值)。

例如,如果您要使用 BLASTN 在核苷酸数据库(nt)中搜索核苷酸序列,并且知道查询序列的 GI 号,则可以使用:

>>> from Bio.Blast import NCBIWWW
>>> result_handle = NCBIWWW.qblast("blastn", "nt", "8332116")

另外,如果我们的查询序列已经存在于 FASTA 格式的文件中,则只需打开文件并以字符串形式读取此记录,然后将其用作查询参数:

>>> 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 字符串(其中将包含现有标识符):

>>> 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() 函数提供什么参数,都应在 handle 对象(默认为 XML 格式)中返回结果。下一步是将 XML 输出解析为表示搜索结果的 Python 对象,但是您可能想先保存输出文件的本地副本。在调试从 BLAST 结果中提取信息的代码时,我发现这特别有用(因为重新运行在线搜索速度很慢,并且浪费了 NCBI 计算机时间)。

我们需要小心一点,因为我们只能使用 result_handle.read() 读取一次 BLAST 输出——再次调用 result_handle.read() 会返回一个空字符串。

>>> with open("my_blast.xml", "w") as out_handle:
...     out_handle.write(result_handle.read())
...
>>> result_handle.close()

完成上面的操作后,结果将保存在文件 my_blast.xml 中,并且原始句柄已提取了所有数据(因此我们将其关闭了)。 但是,BLAST 解析器的解析功能采用了类似于文件句柄的对象,因此我们可以打开保存的文件进行输入:

>>> result_handle = open("my_blast.xml")

现在我们已经将 BLAST 结果重新放回了句柄中,下一步,如果我们准备对它们进行处理,我们可以参考 Biopython 中 Parsing BLAST output 部分的内容,这里不再说明。

NCBIWWW 实现

在了解 NCBIWWW 的实现前,我们先来看一下 NCBI BLAST 对于 API 使用的一些说明:

image
image
  • NCBI BLAST 服务器是共享资源。为了确保整个社区都能使用该服务,他们可能会限制某些高流量用户的搜索。
  • 他们会将在 24 小时内提交 100 次以上搜索的用户的搜索移到较慢的队列中,或者在极端情况下将阻止请求。
  • NCBI BLAST 优先考虑互动的用户,通过网络浏览器的 NCBI 网页的交互式用户不会遇到以上的问题。

对于 API 的使用准则:

  • 与服务器联系的频率不要超过每 10 秒一次。
  • 不要轮询每一个 RID(Request ID) 多于一分钟一次。
  • 使用 URL 参数电子邮件和工具,以便 NCBI 在出现问题时可以与您联系。
  • 如果将提交超过 50 个搜索,则在周末或东部时间东部时间晚上 9 点至凌晨 5 点之间运行脚本。

我们再来看一下 NCBIWWW 在源码层面的处理:

image
image

可以看到 NCBIWWW 从 20秒的延迟开始,然后开始每隔一分钟执行一次 request 轮询,直至任务完成或者任务出现异常。

所以,总的来说,NCBI BLAST API 的使用准则,加上 NCBI BLAST 对用户请求的任务队列处理,甚至 NCBI BLAST 服务器共享资源的限制,以及总用户请求数,这些都可能成为 NCBIWWW.qblast() 异常耗时的原因,这其中还不算个人服务器的网络影响。综上种种原因,如果考虑使用 NCBIWWW.qblast() 执行频繁的序列在线批处理,或许不是一个好的解决方案。

最后,基于 Python 的 NCBI BLAST 在线批处理,如果你有更好的方法,欢迎留言交流。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容