Swiss-Prot 和 ExPASy
解析 Swiss-Prot 文件
Swiss-Prot (https://web.expasy.org/docs/swiss-prot_guideline.html) 是一个手工整理的蛋白质序列数据库。Biopython 可以解析“纯文本”Swiss-Prot 文件格式,这种格式仍然用于 UniProt 知识库,该知识库合并了 Swiss-Prot、TrEMBL 和 PIR-PSD。
虽然我们在下面重点介绍旧的人类可读纯文本格式,但 Bio.SeqIO 可以读取这种格式和较新的 UniProt XML 文件格式,用于注释蛋白质序列。
解析 Swiss-Prot 记录
在第 从网络解析 SwissProt 序列 节中,我们描述了如何将 Swiss-Prot 记录的序列提取为 SeqRecord 对象。或者,你可以将 Swiss-Prot 记录存储在 Bio.SwissProt.Record 对象中,实际上该对象存储了 Swiss-Prot 记录中包含的完整信息。在本节中,我们描述了如何从 Swiss-Prot 文件中提取 Bio.SwissProt.Record 对象。
要解析 Swiss-Prot 记录,我们首先获取 Swiss-Prot 记录的句柄。根据 Swiss-Prot 记录的存储位置和方式,有几种方法可以做到这一点
在本地打开 Swiss-Prot 文件
>>> handle = open("SwissProt/F2CXE6.txt")
打开一个压缩的 Swiss-Prot 文件
>>> import gzip >>> handle = gzip.open("myswissprotfile.dat.gz", "rt")
通过互联网打开 Swiss-Prot 文件
>>> from urllib.request import urlopen >>> url = "https://raw.githubusercontent.com/biopython/biopython/master/Tests/SwissProt/F2CXE6.txt" >>> handle = urlopen(url)
在调用
read之前打开存储在互联网上的文件。通过 ExPASy 数据库(见第 检索 Swiss-Prot 记录 节)通过互联网打开 Swiss-Prot 文件
>>> from Bio import ExPASy >>> handle = ExPASy.get_sprot_raw("F2CXE6")
关键在于,对于解析器来说,句柄是如何创建的并不重要,只要它指向 Swiss-Prot 格式的数据即可。如果句柄以二进制模式打开,解析器会自动将数据解码为 ASCII(Swiss-Prot 使用的编码)。
我们可以使用 Bio.SeqIO,如第 从网络解析 SwissProt 序列 节所述,获取与文件格式无关的 SeqRecord 对象。或者,我们可以使用 Bio.SwissProt 获取 Bio.SwissProt.Record 对象,这些对象更接近底层文件格式。
要从句柄中读取一个 Swiss-Prot 记录,我们使用函数 read()
>>> from Bio import SwissProt
>>> record = SwissProt.read(handle)
如果句柄正好指向一个 Swiss-Prot 记录,应该使用此函数。如果找不到 Swiss-Prot 记录,或者找到多个记录,它都会引发 ValueError。
现在我们可以打印一些关于此记录的信息
>>> print(record.description)
SubName: Full=Plasma membrane intrinsic protein {ECO:0000313|EMBL:BAN04711.1}; SubName: Full=Predicted protein {ECO:0000313|EMBL:BAJ87517.1};
>>> for ref in record.references:
... print("authors:", ref.authors)
... print("title:", ref.title)
...
authors: Matsumoto T., Tanaka T., Sakai H., Amano N., Kanamori H., Kurita K., Kikuta A., Kamiya K., Yamamoto M., Ikawa H., Fujii N., Hori K., Itoh T., Sato K.
title: Comprehensive sequence analysis of 24,783 barley full-length cDNAs derived from 12 clone libraries.
authors: Shibasaka M., Sasano S., Utsugi S., Katsuhara M.
title: Functional characterization of a novel plasma membrane intrinsic protein2 in barley.
authors: Shibasaka M., Katsuhara M., Sasano S.
title:
>>> print(record.organism_classification)
['Eukaryota', 'Viridiplantae', 'Streptophyta', 'Embryophyta', 'Tracheophyta', 'Spermatophyta', 'Magnoliophyta', 'Liliopsida', 'Poales', 'Poaceae', 'BEP clade', 'Pooideae', 'Triticeae', 'Hordeum']
要解析包含多个 Swiss-Prot 记录的文件,我们使用 parse 函数。此函数允许我们迭代文件中的记录。
例如,让我们解析完整的 Swiss-Prot 数据库并收集所有描述。你可以从 ExPASy FTP 站点 下载这个数据库,它是一个名为 uniprot_sprot.dat.gz(大约 300MB)的压缩文件。这是一个包含单个文件 uniprot_sprot.dat(超过 1.5GB)的压缩文件。
如本节开头所述,你可以使用 Python 库 gzip 打开和解压缩 .gz 文件,例如
>>> import gzip
>>> handle = gzip.open("uniprot_sprot.dat.gz", "rt")
但是,解压缩大型文件需要时间,并且每次以这种方式打开文件进行读取时,都需要动态解压缩。因此,如果你有足够的磁盘空间,将文件解压缩到磁盘后,你将节省大量时间,从而获得内部的 uniprot_sprot.dat 文件。然后,你可以像往常一样打开文件进行读取
>>> handle = open("uniprot_sprot.dat")
截至 2009 年 6 月,从 ExPASy 下载的完整 Swiss-Prot 数据库包含 468851 个 Swiss-Prot 记录。构建记录描述列表的一种简洁方法是使用列表推导
>>> from Bio import SwissProt
>>> handle = open("uniprot_sprot.dat")
>>> descriptions = [record.description for record in SwissProt.parse(handle)]
>>> len(descriptions)
468851
>>> descriptions[:5]
['RecName: Full=Protein MGF 100-1R;',
'RecName: Full=Protein MGF 100-1R;',
'RecName: Full=Protein MGF 100-1R;',
'RecName: Full=Protein MGF 100-1R;',
'RecName: Full=Protein MGF 100-2L;']
或者,使用 for 循环遍历记录迭代器
>>> from Bio import SwissProt
>>> descriptions = []
>>> handle = open("uniprot_sprot.dat")
>>> for record in SwissProt.parse(handle):
... descriptions.append(record.description)
...
>>> len(descriptions)
468851
由于这是一个非常大的输入文件,无论哪种方式,在我的新台式电脑上(使用未压缩的 uniprot_sprot.dat 文件作为输入)都需要大约 11 分钟。
从 Swiss-Prot 记录中提取任何你想要的信息同样容易。要查看 Swiss-Prot 记录的成员,请使用
>>> dir(record)
['__doc__', '__init__', '__module__', 'accessions', 'annotation_update',
'comments', 'created', 'cross_references', 'data_class', 'description',
'entry_name', 'features', 'gene_name', 'host_organism', 'keywords',
'molecule_type', 'organelle', 'organism', 'organism_classification',
'references', 'seqinfo', 'sequence', 'sequence_length',
'sequence_update', 'taxonomy_id']
解析 Swiss-Prot 关键词和类别列表
Swiss-Prot 还发布了一个名为 keywlist.txt 的文件,其中列出了 Swiss-Prot 中使用的关键词和类别。该文件以以下形式包含条目
ID 2Fe-2S.
AC KW-0001
DE Protein which contains at least one 2Fe-2S iron-sulfur cluster: 2 iron
DE atoms complexed to 2 inorganic sulfides and 4 sulfur atoms of
DE cysteines from the protein.
SY Fe2S2; [2Fe-2S] cluster; [Fe2S2] cluster; Fe2/S2 (inorganic) cluster;
SY Di-mu-sulfido-diiron; 2 iron, 2 sulfur cluster binding.
GO GO:0051537; 2 iron, 2 sulfur cluster binding
HI Ligand: Iron; Iron-sulfur; 2Fe-2S.
HI Ligand: Metal-binding; 2Fe-2S.
CA Ligand.
//
ID 3D-structure.
AC KW-0002
DE Protein, or part of a protein, whose three-dimensional structure has
DE been resolved experimentally (for example by X-ray crystallography or
DE NMR spectroscopy) and whose coordinates are available in the PDB
DE database. Can also be used for theoretical models.
HI Technical term: 3D-structure.
CA Technical term.
//
ID 3Fe-4S.
...
该文件中的条目可以通过 Bio.SwissProt.KeyWList 模块中的 parse 函数进行解析。然后,每个条目都被存储为 Bio.SwissProt.KeyWList.Record,它是一个 Python 字典。
>>> from Bio.SwissProt import KeyWList
>>> handle = open("keywlist.txt")
>>> records = KeyWList.parse(handle)
>>> for record in records:
... print(record["ID"])
... print(record["DE"])
...
这将打印
2Fe-2S.
Protein which contains at least one 2Fe-2S iron-sulfur cluster: 2 iron atoms
complexed to 2 inorganic sulfides and 4 sulfur atoms of cysteines from the
protein.
...
解析 Prosite 记录
Prosite 是一个包含蛋白质结构域、蛋白质家族、功能位点以及识别它们的模式和概要文件的数据库。Prosite 与 Swiss-Prot 平行开发。在 Biopython 中,Prosite 记录由 Bio.ExPASy.Prosite.Record 类表示,其成员对应于 Prosite 记录中的不同字段。
通常,Prosite 文件可以包含多个 Prosite 记录。例如,完整的 Prosite 记录集可以从 ExPASy FTP 站点 下载为单个文件 (prosite.dat),其中包含 2073 个记录(2007 年 12 月 4 日发布的 20.24 版)。要解析此类文件,我们再次使用迭代器
>>> from Bio.ExPASy import Prosite
>>> handle = open("myprositefile.dat")
>>> records = Prosite.parse(handle)
现在我们可以逐个获取记录并打印一些信息。例如,使用包含完整 Prosite 数据库的文件,我们会发现
>>> from Bio.ExPASy import Prosite
>>> handle = open("prosite.dat")
>>> records = Prosite.parse(handle)
>>> record = next(records)
>>> record.accession
'PS00001'
>>> record.name
'ASN_GLYCOSYLATION'
>>> record.pdoc
'PDOC00001'
>>> record = next(records)
>>> record.accession
'PS00004'
>>> record.name
'CAMP_PHOSPHO_SITE'
>>> record.pdoc
'PDOC00004'
>>> record = next(records)
>>> record.accession
'PS00005'
>>> record.name
'PKC_PHOSPHO_SITE'
>>> record.pdoc
'PDOC00005'
等等。如果你对 Prosite 记录的数量感兴趣,你可以使用
>>> from Bio.ExPASy import Prosite
>>> handle = open("prosite.dat")
>>> records = Prosite.parse(handle)
>>> n = 0
>>> for record in records:
... n += 1
...
>>> n
2073
要从句柄中读取一个 Prosite,你可以使用 read 函数
>>> from Bio.ExPASy import Prosite
>>> handle = open("mysingleprositerecord.dat")
>>> record = Prosite.read(handle)
如果找不到 Prosite 记录,或者找到多个 Prosite 记录,此函数都会引发 ValueError。
解析 Prosite 文档记录
在上面的 Prosite 示例中,record.pdoc 访问号 'PDOC00001'、'PDOC00004'、'PDOC00005' 等等引用 Prosite 文档。Prosite 文档记录可从 ExPASy 获取,作为单个文件,以及包含所有 Prosite 文档记录的一个文件 (prosite.doc)。
我们使用 Bio.ExPASy.Prodoc 中的解析器来解析 Prosite 文档记录。例如,要创建 Prosite 文档记录的所有访问号列表,你可以使用
>>> from Bio.ExPASy import Prodoc
>>> handle = open("prosite.doc")
>>> records = Prodoc.parse(handle)
>>> accessions = [record.accession for record in records]
同样,提供了 read() 函数来从句柄中读取一个 Prosite 文档记录。
解析 Enzyme 记录
ExPASy 的 Enzyme 数据库是关于酶命名法的资料库。典型的 Enzyme 记录如下所示
ID 3.1.1.34
DE Lipoprotein lipase.
AN Clearing factor lipase.
AN Diacylglycerol lipase.
AN Diglyceride lipase.
CA Triacylglycerol + H(2)O = diacylglycerol + a carboxylate.
CC -!- Hydrolyzes triacylglycerols in chylomicrons and very low-density
CC lipoproteins (VLDL).
CC -!- Also hydrolyzes diacylglycerol.
PR PROSITE; PDOC00110;
DR P11151, LIPL_BOVIN ; P11153, LIPL_CAVPO ; P11602, LIPL_CHICK ;
DR P55031, LIPL_FELCA ; P06858, LIPL_HUMAN ; P11152, LIPL_MOUSE ;
DR O46647, LIPL_MUSVI ; P49060, LIPL_PAPAN ; P49923, LIPL_PIG ;
DR Q06000, LIPL_RAT ; Q29524, LIPL_SHEEP ;
//
在此示例中,第一行显示了脂蛋白脂肪酶的 EC(酶委员会)号(第二行)。脂蛋白脂肪酶的别名是“清除因子脂肪酶”、“二酰基甘油脂肪酶”和“二甘油酯脂肪酶”(第 3 到 5 行)。以“CA”开头的行显示了这种酶的催化活性。以“CC”开头的行是注释行。“PR”行显示了 Prosite 文档记录的引用,而“DR”行显示了 Swiss-Prot 记录的引用。并非所有这些条目都一定存在于 Enzyme 记录中。
在 Biopython 中,Enzyme 记录由 Bio.ExPASy.Enzyme.Record 类表示。此记录从 Python 字典派生,其键对应于 Enzyme 文件中使用的两位字母代码。要读取包含一个 Enzyme 记录的 Enzyme 文件,请使用 Bio.ExPASy.Enzyme 中的 read 函数
>>> from Bio.ExPASy import Enzyme
>>> with open("lipoprotein.txt") as handle:
... record = Enzyme.read(handle)
...
>>> record["ID"]
'3.1.1.34'
>>> record["DE"]
'Lipoprotein lipase.'
>>> record["AN"]
['Clearing factor lipase.', 'Diacylglycerol lipase.', 'Diglyceride lipase.']
>>> record["CA"]
'Triacylglycerol + H(2)O = diacylglycerol + a carboxylate.'
>>> record["PR"]
['PDOC00110']
>>> record["CC"]
['Hydrolyzes triacylglycerols in chylomicrons and very low-density lipoproteins
(VLDL).', 'Also hydrolyzes diacylglycerol.']
>>> record["DR"]
[['P11151', 'LIPL_BOVIN'], ['P11153', 'LIPL_CAVPO'], ['P11602', 'LIPL_CHICK'],
['P55031', 'LIPL_FELCA'], ['P06858', 'LIPL_HUMAN'], ['P11152', 'LIPL_MOUSE'],
['O46647', 'LIPL_MUSVI'], ['P49060', 'LIPL_PAPAN'], ['P49923', 'LIPL_PIG'],
['Q06000', 'LIPL_RAT'], ['Q29524', 'LIPL_SHEEP']]
如果找不到 Enzyme 记录,或者找到多个 Enzyme 记录,read 函数都会引发 ValueError。
完整的 Enzyme 记录集可以从 ExPASy FTP 站点 下载为单个文件 (enzyme.dat),其中包含 4877 个记录(2009 年 3 月 3 日发布)。要解析此类包含多个 Enzyme 记录的文件,请使用 Bio.ExPASy.Enzyme 中的 parse 函数获取迭代器
>>> from Bio.ExPASy import Enzyme
>>> handle = open("enzyme.dat")
>>> records = Enzyme.parse(handle)
现在我们可以逐个遍历这些记录。例如,我们可以创建所有可用的 Enzyme 记录的 EC 号列表
>>> ecnumbers = [record["ID"] for record in records]
访问 ExPASy 服务器
Swiss-Prot、Prosite 和 Prosite 文档记录可以从 ExPASy 网站服务器下载 https://www.expasy.org。ExPASy 提供四种查询方式
- get_prodoc_entry
以 HTML 格式下载 Prosite 文档记录
- get_prosite_entry
以 HTML 格式下载 Prosite 记录
- get_prosite_raw
以原始格式下载 Prosite 或 Prosite 文档记录
- get_sprot_raw
以原始格式下载 Swiss-Prot 记录
要从 Python 脚本访问此 Web 服务器,我们使用 Bio.ExPASy 模块。
检索 Swiss-Prot 记录
假设我们正在研究兰花的查尔酮合酶(参见部分 一个使用示例,了解为什么我们会对兰花感兴趣)。查尔酮合酶参与植物中的黄酮类生物合成,黄酮类生物合成产生许多酷炫的东西,例如色素颜色和紫外线防护剂。
如果你在 Swiss-Prot 上搜索,你可以找到三种兰花查尔酮合酶蛋白,ID 号为 O23729、O23730、O23731。现在,让我们编写一个脚本,获取这些蛋白并解析出一些有趣的信息。
首先,我们使用 Bio.ExPASy 的 get_sprot_raw() 函数获取记录。这个函数非常棒,因为你可以向它提供一个 ID,然后它会返回一个指向原始文本记录的句柄(没有 HTML 要处理!)。然后我们可以使用 Bio.SwissProt.read 来提取 Swiss-Prot 记录,或者使用 Bio.SeqIO.read 来获取 SeqRecord。以下代码实现了我的描述
>>> from Bio import ExPASy
>>> from Bio import SwissProt
>>> accessions = ["O23729", "O23730", "O23731"]
>>> records = []
>>> for accession in accessions:
... handle = ExPASy.get_sprot_raw(accession)
... record = SwissProt.read(handle)
... records.append(record)
...
如果提供给 ExPASy.get_sprot_raw 的登录号不存在,那么 SwissProt.read(handle) 将会引发 ValueError。你可以捕获 ValueException 异常来检测无效的登录号
>>> for accession in accessions:
... handle = ExPASy.get_sprot_raw(accession)
... try:
... record = SwissProt.read(handle)
... except ValueException:
... print("WARNING: Accession %s not found" % accession)
... records.append(record)
...
使用 UniProt 搜索
现在,你可能会注意到,我事先知道记录的登录号。确实,get_sprot_raw() 需要条目名称或登录号。当你没有这些信息时,你可以使用 UniProt 来搜索它们。你也可以使用 UniProt 包来以编程方式搜索蛋白质。
例如,让我们搜索来自特定生物体(生物体 ID:2697049)的已审查蛋白质。我们可以使用以下代码来实现
>>> from Bio import UniProt
>>> query = "(organism_id:2697049) AND (reviewed:true)"
>>> results = list(UniProt.search(query))
The UniProt.search 方法返回一个搜索结果的迭代器。迭代器每次返回一个结果,并在需要时从 UniProt 获取更多结果,直到返回所有结果。我们可以有效地从这个迭代器创建列表,因为这个查询只返回少量结果(在编写本文时为 17 个)。
让我们尝试一个返回更多结果的搜索。在编写本文时,查询“Insulin AND (reviewed:true)”有 5,147 个结果。我们可以使用切片来获取前 50 个结果的列表。
>>> from Bio import UniProt
>>> from itertools import islice
>>> query = "Insulin AND (reviewed:true)"
>>> results = UniProt.search(query, batch_size=50)[:50]
你可以使用 len 方法获取搜索结果的总数(无论批次大小)。
>>> from Bio import UniProt
>>> query = "Insulin AND (reviewed:true)"
>>> result_iterator = UniProt.search(query, batch_size=0)
>>> len(result_iterator)
5147
检索 Prosite 和 Prosite 文档记录
Prosite 和 Prosite 文档记录可以以 HTML 格式或原始格式检索。要使用 Biopython 解析 Prosite 和 Prosite 文档记录,你应该以原始格式检索记录。但是,出于其他目的,你可能对这些记录的 HTML 格式感兴趣。
要以原始格式检索 Prosite 或 Prosite 文档记录,请使用 get_prosite_raw()。例如,要下载 Prosite 记录并以原始文本格式打印它,请使用
>>> from Bio import ExPASy
>>> handle = ExPASy.get_prosite_raw("PS00001")
>>> text = handle.read()
>>> print(text)
要检索 Prosite 记录并将其解析为 Bio.Prosite.Record 对象,请使用
>>> from Bio import ExPASy
>>> from Bio import Prosite
>>> handle = ExPASy.get_prosite_raw("PS00001")
>>> record = Prosite.read(handle)
相同的函数可用于检索 Prosite 文档记录并将其解析为 Bio.ExPASy.Prodoc.Record 对象
>>> from Bio import ExPASy
>>> from Bio.ExPASy import Prodoc
>>> handle = ExPASy.get_prosite_raw("PDOC00001")
>>> record = Prodoc.read(handle)
对于不存在的登录号,ExPASy.get_prosite_raw 返回一个指向空字符串的句柄。当遇到空字符串时,Prosite.read 和 Prodoc.read 将会引发 ValueError。你可以捕获这些异常来检测无效的登录号。
函数 get_prosite_entry() 和 get_prodoc_entry() 用于以 HTML 格式下载 Prosite 和 Prosite 文档记录。要创建显示一个 Prosite 记录的网页,你可以使用
>>> from Bio import ExPASy
>>> handle = ExPASy.get_prosite_entry("PS00001")
>>> html = handle.read()
>>> with open("myprositerecord.html", "w") as out_handle:
... out_handle.write(html)
...
类似地,对于 Prosite 文档记录,你可以使用
>>> from Bio import ExPASy
>>> handle = ExPASy.get_prodoc_entry("PDOC00001")
>>> html = handle.read()
>>> with open("myprodocrecord.html", "w") as out_handle:
... out_handle.write(html)
...
对于这些函数,无效的登录号会以 HTML 格式返回错误消息。
扫描 Prosite 数据库
ScanProsite 允许你通过提供 UniProt 或 PDB 序列标识符或序列本身来在线扫描蛋白质序列以查找 Prosite 数据库。有关 ScanProsite 的更多信息,请参阅 ScanProsite 文档 以及 ScanProsite 的编程访问文档。
你可以使用 Biopython 的 Bio.ExPASy.ScanProsite 模块从 Python 扫描 Prosite 数据库。此模块既可以帮助你以编程方式访问 ScanProsite,也可以解析 ScanProsite 返回的结果。要扫描以下蛋白质序列中的 Prosite 模式
MEHKEVVLLLLLFLKSGQGEPLDDYVNTQGASLFSVTKKQLGAGSIEECAAKCEEDEEFT
CRAFQYHSKEQQCVIMAENRKSSIIIRMRDVVLFEKKVYLSECKTGNGKNYRGTMSKTKN
你可以使用以下代码
>>> sequence = (
... "MEHKEVVLLLLLFLKSGQGEPLDDYVNTQGASLFSVTKKQLGAGSIEECAAKCEEDEEFT"
... "CRAFQYHSKEQQCVIMAENRKSSIIIRMRDVVLFEKKVYLSECKTGNGKNYRGTMSKTKN"
... )
>>> from Bio.ExPASy import ScanProsite
>>> handle = ScanProsite.scan(seq=sequence)
通过执行 handle.read(),你可以获取以原始 XML 格式呈现的搜索结果。相反,让我们使用 Bio.ExPASy.ScanProsite.read 将原始 XML 解析为 Python 对象
>>> result = ScanProsite.read(handle)
>>> type(result)
<class 'Bio.ExPASy.ScanProsite.Record'>
一个 Bio.ExPASy.ScanProsite.Record 对象是从列表派生的,列表中的每个元素都存储一个 ScanProsite 命中。此对象还存储命中次数以及 ScanProsite 返回的搜索序列次数。此 ScanProsite 搜索产生了六次命中
>>> result.n_seq
1
>>> result.n_match
1
>>> len(result)
1
>>> result[0]
{'sequence_ac': 'USERSEQ1', 'start': 16, 'stop': 98, 'signature_ac': 'PS50948', 'score': '8.873', 'level': '0'}
其他 ScanProsite 参数可以作为关键字参数传递;有关更多信息,请参阅 ScanProsite 的编程访问文档。例如,传递 lowscore=1 以包含低级别分数匹配,让我们找到一个额外的命中
>>> handle = ScanProsite.scan(seq=sequence, lowscore=1)
>>> result = ScanProsite.read(handle)
>>> result.n_match
2