Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 按序列大小对fasta排序_Python 3.x_Sorting_Bioinformatics_Fasta - Fatal编程技术网

Python 3.x 按序列大小对fasta排序

Python 3.x 按序列大小对fasta排序,python-3.x,sorting,bioinformatics,fasta,Python 3.x,Sorting,Bioinformatics,Fasta,我目前想按序列大小对hudge fasta文件(+10**8行和序列)进行排序。fasta是生物学中一种明确定义的格式,用于存储序列(遗传或蛋白质): >id1 序列1可以在几行上 >id2 序列2 我运行了一个以tsv格式提供信息的工具: 标识、长度和标识的位置(以字节为单位) 现在我要做的是按照长度列对这个文件进行排序,然后解析这个文件并使用seek检索相应的序列,然后将它附加到一个新文件中 # this fonction will get the sequence using seek

我目前想按序列大小对hudge fasta文件(+10**8行和序列)进行排序。fasta是生物学中一种明确定义的格式,用于存储序列(遗传或蛋白质):

>id1

序列1可以在几行上

>id2

序列2

我运行了一个以tsv格式提供信息的工具:

标识、长度和标识的位置(以字节为单位)

现在我要做的是按照长度列对这个文件进行排序,然后解析这个文件并使用seek检索相应的序列,然后将它附加到一个新文件中

# this fonction will get the sequence using seek
def get_seq(file, bites):  

    with open(file) as f_:
        f_.seek(bites, 0) # go to the line of interest
        line = f_.readline().strip() # this line is the begin of the 
                                     #sequence
        to_return = "" # init the string which will contains the sequence

        while not line.startswith('>') or not line:  # while we do not 
                                                     # encounter another identifiant
        to_return += line
        line = f_.readline().strip()

    return to_return
# simply append to a file the id and the sequence
def write_seq(out_file, id_, sequence):

    with open(out_file, 'a') as out_file:
        out_file.write('>{}\n{}\n'.format(id_.strip(), sequence))

# main loop will parse the index file and call the function defined below
with open(args.fai) as ref:

    indice = 0

    for line in ref:

        spt = line.split()
        id_ = spt[0]
        seq = get_seq(args.i, int(spt[2]))
        write_seq(out_file=args.out, id_=id_, sequence=seq)

我的问题是以下是真的很慢,这是正常的(需要几天)?我还有别的办法吗?我不是一个纯粹的信息学家,所以我可能会错过一些要点,但我相信索引文件和使用seek是实现这一点的最致命的方法。我错了吗?

似乎为每个序列打开两个文件可能会对运行时间造成很大影响。您可以将文件句柄传递给get/write函数,而不是文件名,但我建议使用已建立的fasta解析器/索引器,如biopython或samtools。下面是一个使用samtools的(未经测试的)解决方案:

subprocess.call(["samtools", "faidx", args.i])
with open(args.fai) as ref:

    for line in ref:

        spt = line.split()
        id_ = spt[0]
        subprocess.call(["samtools", "faidx", args.i, id_, ">>", args.out], shell=True)

bash和一些基本的unix命令(csplit是线索)怎么样?我写了这个简单的脚本,但是你可以自定义/改进它。它不是高度优化的,也不使用索引文件,但可能运行得更快

csplit -z -f tmp_fasta_file_ $1 '/>/' '{*}'

for file in tmp_fasta_file_*
do
  TMP_FASTA_WC=$(wc -l < $file | tr -d ' ')
  FASTA_WC+=$(echo "$file $TMP_FASTA_WC\n")
done

for filename in $(echo -e $FASTA_WC | sort -k2 -r -n | awk -F" " '{print $1}')
do
  cat "$filename" >> $2
done

rm tmp_fasta_file*
csplit-z-f tmp\u fasta\u文件\uu$1'/>/'{*}
对于tmp_fasta_文件中的文件_*
做
TMP_FASTA_WC=$(WC-l<$file | tr-d'')
FASTA_WC+=$(回显“$文件$TMP_FASTA_WC\n”)
完成
文件名为$(echo-e$FASTA_WC | sort-k2-r-n | awk-F“”{print$1})
做
cat“$filename”>>$2
完成
rm tmp_fasta_文件*

第一个位置参数是指向fasta文件的文件路径,第二个位置参数是用于输出的文件路径,即
/script.sh input.fasta output.fasta

使用修改后的fastq sort版本(当前位于),我们可以使用添加的
-L
选项将文件转换为fastq格式,并转换回fasta:

cat test.fasta \
    | tee >(wc -l > nb_lines_fasta.txt) \
    | bioawk -c fastx '{l = length($seq); printf "@"$name"\n"$seq"\n+\n%.*s\n", l, "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"}' \
    | tee >(wc -l > nb_lines_fastq.txt) \
    | fastq-sort -L \
    | tee >(wc -l > nb_lines_fastq_sorted.txt) \
    | bioawk -c fastx '{print ">"$name"\n"$seq}' \
    | tee >(wc -l > nb_lines_fasta_sorted.txt) \
    > test_sorted.fasta
fasta->fastq转换步骤非常难看。我们需要生成与序列长度相同的伪fastq质量。我发现(bio)awk没有比这个基于本文末尾提到的“动态宽度”的攻击更好的方法了

iiii…
字符串应该比输入序列的最长长度长,否则,将获得无效的fastq,当转换回fasta时,bioawk似乎会默默地跳过这些无效读取

在上面的示例中,我添加了计算行数的步骤。如果行号不一致,可能是因为
iiii…
字符串太短

生成的fasta文件将首先具有较短的序列。 要获取文件顶部的最长序列,请将
-r
选项添加到
fastq sort

请注意,
fastq sort
/tmp
中写入中间文件。如果由于某种原因,在删除它们之前中断,您可能希望手动清理
/tmp
,而不是等待下次重新启动

编辑 实际上,我找到了一种更好的方法来生成与序列长度相同的伪质量:只需使用序列本身:

cat test.fasta \
    | bioawk -c fastx '{print "@"$name"\n"$seq"\n+\n"$seq}' \
    | fastq-sort -L \
    | bioawk -c fastx '{print ">"$name"\n"$seq}' \
    > test_sorted.fasta

这个解决方案更干净(速度稍快),但我保留了上面的原始版本,因为
printf
的“动态宽度”功能和使用
tee
检查中间数据长度可能很有趣。

您也可以非常方便地使用
awk
,检查下面的代码:

awk '/^>/ {printf("%s%s\t",(N>0?"\n":""),$0);N++;next;} {printf("%s",$0);} END {printf("\n");}'  input.fasta  |\
awk -F '\t' '{printf("%d\t%s\n",length($2),$0);}' |\
sort -k1,1n | cut -f 2- | tr "\t" "\n"

此方法和其他方法已发布(例如,使用BBMap的
sortbyname.sh
script),对于类似这样的问题,我强烈推荐这个社区。

samtoosl faidx是我用来索引我的文件的工具。对于打开的文件,你显然是对的,我通过这种方式获得了很多速度,谢谢。事实上,samtools faidx的文档说明了“为了使用samtools faidx索引,FASTA文件必须是表单的文本文件“所以我想faidx是一个索引工具,它可以从索引的Fasts中获取序列。就像很多生物信息学软件一样,文档很粗略,但它说faidx可以“以FASTA格式索引引用序列或从索引引用序列中提取子序列。如果未指定区域,faidx将索引文件并在磁盘上创建.fai。如果指定了区域,将检索子序列并以FASTA格式打印到标准输出。“如果只给出不带坐标的序列名,它会将整个序列视为区域,这肯定比python更有效,谢谢。这很有趣,显然速度更快,但它必须创建超过10**8子文件。每个子文件的最小大小为4,0kb不是一个好的解决方案,但我肯定应该寻找C/C++代码,而不是pythonWhy 10**8子文件?这个脚本为每个序列创建文件,而不是每行…我有10多个**8序列是我的错,我将编辑问题。更具体地说,这就是改变一切;)所以4kb的限制很痛苦,因为有很多短序列?4kb只是一个空文件的重量,我错了吗?但基本上是的,有100到500个字符之间的序列。我没有尝试使用10^8个序列,但对于我包含大约450万个短序列的示例文件,以下基于Biopython的方法使用了几GB的RAM工作:
sortedrecs=sorted(SeqIO.parse(/tmp/test.fasta),format=“fasta”),key=lambda rec:len(rec.seq))
。在python中,这可能不是表示fasta序列最简单的方法,因此可能还有改进的余地。另一个想法是修改fastq排序代码,使其使用序列长度进行排序().我得到了一些基于fastq工具的东西,但它需要fastq格式的输入:我请求将其添加到fastq工具:我添加了一个