-1

私の研究では、生物学的シーケンス (fasta 形式) の巨大なテキスト ファイル (10gi) を処理する必要があり、より正確には、特定の ID を持つ特定のシーケンスをスペシャルに配置する必要があります。fasta シーケンスは次のようなものです。

>id|id_number (例: 102574)|もの

ATGCGAT.... ATGTC.. (複数行)

そこで、Python のマルチプロセッシング ライブラリを使用して検索を並列化する (そして 8 つの CPU を使用する) ために、これらの大きなファイルのチャンクを検索するスクリプトを作成しました。

マルチプロセス クラスに挿入する関数は次のとおりです。

idlist=inP[0] # list of good id 
    filpath=inP[1] # chunck of the big file
    idproc=inP[2]   # id of the process

    #######################
    fil=filpath.split('\n')
    del filpath
    f=open('seqwithid{0}'.format(idproc),'w')
    def lineiter():
        for line in fil:
            yield line
    it=lineiter()
    line=it.next()

    while 1:
        try:
            ids=line.split('|')[1].split('locus')[0].partition('ref')[0]
            #print ids
            while ids[0].isalpha():
                ids=ids[1:]
        except Exception:
            pass
        else:
            if ids in idlist: 
                f.write(line+'\n')
                while 1:
                    try:
                        line=it.next()
                    except Exception:
                        break
                    if line and line[0]!='>':
                        f.write(line+'\n')
                    else:
                        break
        try:                
            line=it.next()
        except Exception:
            break
        while  not line or line[0]!='>':
            try:
                line=it.next()
            except Exception:
                break
    f.close()

速度を向上させるために、このコードを C で 4 つの関数で書き直しました。

ファイルをチャンクに分割します。

f1=fopen(adr, "r");
if (f1==0){printf("wrong sequences file: %s\n",adr);exit(1);}

fstream = (char *) malloc((end-begin)*sizeof(char) );
fseek(f1,begin,SEEK_CUR);
fread(fstream,sizeof(char)*(end-begin-1),1,f1);
adrtampon=fgetc(f1);

while (!(feof(f1)) && adrtampon!=ter)
{
    sprintf(fstream,"%s%c",fstream,adrtampon);
    adrtampon=fgetc(f1);
}
fclose(f1);

「>」文字が見つかるまで、メイン関数でチャンクを実行します。

adrtampon=fstream[0];   
i=0;

while(adrtampon!='\0' )
{
    adrtampon=fstream[i];
    if (adrtampon==ter)
    {
        sprintf(id,"%s",seekid((fstream+i)));

        if (checkidlist(id,tab,size)==0) 
        {
            i++;
            fputc('>',f2);
            adrtampon=fstream[i];
            while (adrtampon!='\0' &&  adrtampon!=ter)  
            {
                fputc(adrtampon,f2);
                i++;
                adrtampon=fstream[i];
            }
            i--;
        }
    }
    i++;
}

そして、「>」を見つけたら、最初に2つの「|」の間のシーケンスのIDを抽出します そして、別の単純な関数 (idlist の if id と同様) を使用して、intersting id のライブラリをループします。この関数は、まだマルチプロセッシング クラスを使用している python 関数で呼び出されます。 1 つのプロセスでも python コード。(チャンクではなくファイルを直接扱うとき、Cでより良いパフォーマンスを得ることができますが、マルチプロセスのファイルへの同時アクセスのために1つのプロセスでしか得られません(私は思います))私のCコードを改善し、その理由を説明するための提案それはpythonの同等のものより遅いですか????? どうもありがとう!!(特にここまで読んだ方!)

4

1 に答える 1

0

おそらく 10GB のファイルはメモリに収まりません (メモリに収まる場合は、ここで行ったように実行できます)。したがって、それを読み取って処理する唯一の方法は、一部を読み取り、その部分を処理し、次の部分を読み取ることです。 . 行の長さが制限されている場合、 fgets() が最もエレガントです。それ以外の場合は、一度に 1 文字ずつ読み取り、小さなステートマシンを使用して処理を行うことができます。バッファサイズのチャンクを読み取ることは可能ですが、論理行がバッファ境界を越えるため、より困難です。

于 2012-04-25T13:07:45.990 に答える