首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用外部库kseq.h读取多个fasta序列

使用外部库kseq.h读取多个fasta序列
EN

Stack Overflow用户
提问于 2014-07-11 09:49:13
回答 1查看 256关注 0票数 0

我试图使用外部头文件kseq.h (如:http://lh3lh3.users.sourceforge.net/kseq.shtml )从一个大fasta文件(包含80000 fasta序列)中找到用户提供的5个in/名称的fasta序列。当我在for循环中运行程序时,我必须一次又一次地打开/关闭大fasta文件(代码中有注释),这使得计算时间变慢。相反,如果我只在循环之外打开/关闭一次,那么如果程序遇到一个在大fasta文件中不存在的条目,即它到达文件的末尾,程序就会停止。谁能建议如何在不损失计算时间的情况下得到所有的序列。守则是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <zlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ext_libraries/kseq.h"

KSEQ_INIT(gzFile, gzread)

int main(int argc, char *argv[])
{
    char gwidd_ids[100];
    kseq_t *seq;
    int i=0, nFields=0, row=0, col=0;
    int size=1000, flag1=0, l=0, index0=0;

    printf("Opening file %s\n", argv[1]);

    char **gi_ids=(char **)malloc(sizeof(char *)*size);
    for(i=0;i<size;i++)
    {
        gi_ids[i]=(char *)malloc(sizeof(char)*50);
    }
    FILE *fp_inp = fopen(argv[1], "r");
    while(fscanf(fp_inp, "%s", gwidd_ids) == 1)
    {
        printf("%s\n", gwidd_ids);
        strcpy(gi_ids[index0], gwidd_ids);
        index0++;
    }   
    fclose(fp_inp);

    FILE *f0 = fopen("xxx.txt", "w");
    FILE *f1 = fopen("yyy.txt", "w");
    FILE *f2 = fopen("zzz", "w");

    FILE *instream = NULL;
    instream = fopen("fasta_seq_uniprot.txt", "r"); 
    gzFile fpf = gzdopen(fileno(instream), "r");

    for(col=0;col<index0;col++)
    {
        flag1=0;
//      FILE *instream = NULL;
//      instream = fopen("fasta_seq_nr_uniprot.txt", "r"); 
//      gzFile fpf = gzdopen(fileno(instream), "r");
        kseq_t *seq = kseq_init(fpf); 
        while((kseq_read(seq)) >= 0 && flag1 == 0)
        {
            if(strcasecmp(gi_ids[col], seq->name.s) == 0)
            {
                fprintf(f1, ">%s\n", gi_ids[col]);
                fprintf(f2, ">%s\n%s\n", seq->name.s, seq->seq.s);
                flag1 = 1;
            }
        }
        if(flag1 == 0)
        {
            fprintf(f0, "%s\n", gi_ids[col]);
        }
        kseq_destroy(seq);
//      gzclose(fpf); 
    }
    gzclose(fpf); 

    fclose(f0);
    fclose(f1);
    fclose(f2);

    for(i=0;i<size;i++)
    {
        free(gi_ids[i]);
    }
    free(gi_ids);

    return 0;
}   

inputfile (fasta_seq_uniprot.txt)的几个例子是:

P38077

用户输入文件为P 37592\n Q8IUX1\n B3GNT2\n Q81U58\n P 70453\n

EN

回答 1

Stack Overflow用户

发布于 2014-07-11 11:48:04

你的问题看上去和你想的有点不同。程序在试图检索数据文件中不存在的序列后停止,这是一个事实的结果,即它从不重绕输入。因此,即使对于仅包含在数据文件中的序列的查询列表,如果请求的序列it与数据文件的顺序不同,那么程序将无法找到其中的一些序列(在寻找先前列出的序列时,它会传递它们,永远不会返回)。

此外,我认为您所观察到的节省时间可能来自于只对文件进行一次传递,而不是对每个请求的序列进行(部分)传递,而不是只打开一次。打开和关闭一个文件有点昂贵,但远远比不上从文件中读取几十或数百千字节。

为了直接回答你的问题,我认为你需要采取以下步骤:

  1. kseq_init(seq)调用移至循环之前。
  2. kseq_destroy(seq)调用移到循环之后。
  3. 将对kseq_rewind(seq)的调用作为循环中的最后一条语句。

这将使您的程序再次正确,但它可能会扼杀您几乎所有的时间节省,因为您将返回到扫描文件从一开始的每一个请求的序列。

您使用的库似乎只支持顺序访问。因此,快速完成正确的任务的最有效方法是反转逻辑:在外部循环中一次读取一个序列,测试每个序列是否与所请求的序列匹配。

假设所请求的序列列表只包含几个条目,就像您的示例一样,您可能不需要对匹配进行更好的测试,只需要使用内部循环来测试每个请求的序列id和当前序列。但是,如果查询列表可能要长得多,那么可以考虑将它们放在哈希表中,或者按照与数据文件相同的顺序对它们进行排序,以便能够更有效地进行匹配测试。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24703638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文