Rosalind工具库: Entrez搜索NCBI资源库

Introduction to Protein Databases

蛋白质数据库中心UniProt提供了蛋白详细的注释,如功能描述,功能与结构,翻译后修饰。它还支持蛋白相似性搜索,分类分析和文献引用等。

已知给定一个uniprot id,可以通过链接"http://www.uniprot.org/uniprot/uniprot_id.txt"或"http://www.uniprot.org/uniprot/uniprot_id" 获取关于该编号的详细描述。 通过编程的方式根据一个uniprot ID获取其参与的生物学进程(biological processes)

我使用Go的os.Args读取命令行参数中的编号,使用"net/http"获取响应, 使用"ioutil.ReadAll"获取响应中主体,返回字符数组。利用正则表达式进行解析,然后使用for循环提取出目标区段。

package main

import (
    "net/http"
    "fmt"
    "os"
    "log"
    "io/ioutil"
    "regexp"
)

func main(){
    id := os.Args[1]
    link := "http://www.uniprot.org/uniprot/" + id + ".txt"
    resp, err := http.Get(link)
    if err != nil{
        log.Fatal(err)
    }
    content, err := ioutil.ReadAll(resp.Body)
    resp.Body.Close()
    if err != nil{
        log.Fatal(err)
    }
    re := regexp.MustCompile("P:(.*?);")
    BP := re.FindAllStringSubmatch(string(content[:]),-1)
    for i,n := 0, len(BP); i<n; i++{
        fmt.Println(BP[i][1])
    }
}

GenBank Introduction

分子生物学家可获取的最大的整合型数据库就是GenBank, 它包含了几乎所有公共的DNA序列和蛋白序列。 GenBank最早由NCBI在1982年建立,现在30多年过去了,里面存储的数据量超乎你的想象。

每个GenBank都有唯一的识别号,用于提取全序列,比如说CAA79696,NP_778203, 263191547, BC043443, NM_002020. 当然还可以用一些关键字搜索一类序列。

问题:GenBank包括如下几个子类,如Nucleotide, GSS(Genome Survey Sequence), EST(Expressed Sequene Tags). 为了精确从这些数据库中找到自己目标,需要用到一些搜索语法,比如说(Drosophila[All Fields])表示在所有区域中搜索Drosophila。 那么给定一个物种名,和两个日期,找到在这段时间内该物种上传到GenBank的氨基酸数。

解决方案:NCBI提供Entrez用于检索它存放的所有数据,可供检索的数据库

Entrez DatabaseUID common nameE-utility Database Name
BioProjectBioProject IDbioproject
BioSampleBioSample IDbiosample
BiosystemsBSIDbiosystems
BooksBook IDbooks
Conserved DomainsPSSM-IDcdd
dbGaPdbGaP IDgap
dbVardbVar IDdbvar
EpigenomicsEpigenomics IDepigenomics
ESTGI numbernucest
GeneGene IDgene
GenomeGenome IDgenome
GEO DatasetsGDS IDgds
GEO ProfilesGEO IDgeoprofiles
GSSGI numbernucgss
HomoloGeneHomoloGene IDhomologene
MeSHMeSH IDmesh
NCBI C++ ToolkitToolkit IDtoolkit
NCBI Web SiteWeb Site IDncbisearch
NLM CatalogNLM Catalog IDnlmcatalog
NucleotideGI numbernuccore
OMIAOMIA IDomia
PopSetPopSet IDpopset
ProbeProbe IDprobe
ProteinGI numberprotein
Protein ClustersProtein Cluster IDproteinclusters
PubChem BioAssayAIDpcassay
PubChem CompoundCIDpccompound
PubChem SubstanceSIDpcsubstance
PubMedPMIDpubmed
PubMed CentralPMCIDpmc
SNPrs numbersnp
SRASRA IDsra
StructureMMDB-IDstructure
TaxonomyTaxIDtaxonomy
UniGeneUniGene Cluster IDunigene
UniSTSSTS IDunists

并提供了相应的网页APIhttps://eutils.ncbi.nlm.nih.gov/entrez/eutils/, 按照要求构建URL发起请求后就能返回目标响应用于解析。为了避免对服务器造成太大压力,NCBI对请求有一定的限制限制,每一秒不超过3个请求, 除非你在请求中带上了API_KEY

API key可以在https://www.ncbi.nlm.nih.gov/account/申请,允许每秒10个请求。考虑到国内这个网速,我觉得应该是用不到的。

Entrez搜索语法:

  • Boolean操作: AND OR NOT
  • 限定领域: [], 如 horse[Organism]
  • 日期或其他范围: :, 如日期 2015/3/1:2016/4/30[Publication Date], 如序列长度110:500[Sequence Length]

构建URL: 以样本数据Anthoxanthum 2003/7/25 2005/12/27为例,搜索语法为`Anthoxanthum[Organsim] AND 2003/7/25:2005/12/27[Publication Date],转换成URL link就是

https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=nuccore&term=Anthoxanthum[Organsim]+AND+2003/7/25:2005/12/27[Publication Date]

如果搜索语法中有"和"#", 需要转换成"%22","%23", []外的空格要用"+"代替,[]()内空格要用"%20"替换。

解决这个问题不能想的太复杂,我们需要假设输入时是"Anthoxanthum[Organsim]+AND+2003/7/25:2005/12/27[Publication Date]",而不是Anthoxanthum 2003/7/25 2005/12/27, 这样子我们就只需要构建URL link, 然后发送请求解析响应的xml就行

package main

import (
        "fmt"
        "io/ioutil"
        "log"
        "net/http"
        "os"
        "encoding/xml"
)

// the base url link of entrez API
const BASE = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"

func buildLink(db, query string) string {
        link := BASE + "?db=" + db + "&term=" + query
        return link
}

func eSearch(link string) {
        resp, err := http.Get(link)
        if err != nil {
                log.Fatal(err)
        }
        body, err := ioutil.ReadAll(resp.Body)
        resp.Body.Close()
        if err != nil {
                log.Fatal(err)
        }
}
type eSearchResult struct {
        Count  string   `xml:"Count"`
        RetMax string   `xml:"RetMax"`
        IdList []string `xml:"IdList>Id"`
}
func main() {
        db := os.Args[1]
        query := os.Args[2]
        link := buildLink(db, query)
        fmt.Println(link)
        content := eSearch(link)
        result := eSearchResult{}
        err := xml.Unmarshal(content, &result)
        if err != nil {
                fmt.Printf("err: %v", err)
                return
        }
        fmt.Printf("Count:%s\n", result.Count)
        fmt.Printf("Idlist:%v\n", result.IdList)
}
}

读取命令行的字符串,第一个为数据库,第二个为请求。 将参数传入后构建成link,使用"net/http"发起请求,将得到的响应用ioutil.ReadAll读取保存为字符数组. 然后定义结构体用来保存XML的解析结果。xml.Unmarshal的使用涉及到interface的知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值