【问题标题】:Processing FASTQ files based on mate pair length根据配对长度处理 FASTQ 文件
【发布时间】:2015-05-01 08:50:00
【问题描述】:

以下文件是一个双端 fastq 文件的两个 mate,我想根据它们的长度将每个 fastq 分开。

mate1.fq

@SRR127.1
TGGTTATGATGTTTGTGTAGGAATAGAAATTTTGATTAAGATATTAGTGAAATTTGAATGTAGTTTATTTGGAAGTTATGGAGAGTTTATATTGTATTTATGTTTATTGTTGTAGATTTATATTTATGTGTATATATTAGTTTTTTTGTGT
+
ABAAAF4FFFFFGGGGGGFFGGFGHGFGHHHHHGGCFFGHHHHH5FDBED55DGGFEGFHHHGBHDDHHHFF3AB3FFG5CBGBEF5BD5DGFEGHFAGAFEDGHGFHHGHGEFFGFGGHFEGHHFHGBEBGHHHHGHBHHFHHGGFGHH2
@SRR127.2
TATGGTAAGAAAATTGAAAATTATAAAAAATGAAAAATGTTTATTTGATGATTTGAAAAATGATGAAATTATTGAAAAATGTGAAAAATGAGAAATGTATATTGTAGGATTTGGAATATGGTGAGATAAATGAAAATTATAGTAAATG
+
AABAA5@D4@5CFFCA55FFGGHDGFHFFCC45DGFA2FA5DD55AAAA55DDBDEDDBGGFF5BA5DDABF5D5B5FF1ADFB5EDGHFG5@BFBD55D5FFB@@5@GBGEFBGHHGB@DBBFHFBDG3B43FFH@FGFHH?FHHHH

mate2.fq

@SRR127.1
ACCTATAAAAAAACCATATCAATAACTATAAAATCTTTATAAAATCCCACCCAATTAAAAAAAAATAAATTAATACATATAAAACCTTAAACACATAAAACATAATCACATACTATATAAACAATTACTATCACTACTAAACACCTAATA
+
>AA?AF13B@D@1EFCGGGFFG3EBGHHHBB2FGHHGHGFDGHHDFEGFHGGGHG1FFF1GGCGGGBGHHHHHFHHHHFHEGGFHF0BD1FGHHAGEGHFHHHFGGFHHGHHHFHHGGFHBGHFED1FBGFGFHDGHGHFGG1GB0GFHH
@SRR127.2
CTATTTCTCATTTTTTTATAATTTTCAATTCTCTTACCATATTCCACATCCTACACTAAACATTTCTAAATTTTCCACCTTTTTCTATTTTTCTCACCATATTTCATATCCTAAAAAACATATTCCTCATTTACTATAATTTTCAATTATC
+
11>>AFFDFF3@FFF?EFFGFBGHFDFA33D2FF2GGHFE12DD221AF1F1E1BG1GGBFBGGEGHDAABGAGDFABGG1BBDF12A2@2BG@2@DEFFF2B2@2222BB2211FGEE/11@22B2>1B22F2>GBGBD22BGD2>2B22

我编写了以下代码来执行此操作,但我只收到第二个文件 (mate2.fq) 的奇怪错误,而它们都有 151 bp 的读取。

#!/usr/bin/perl

use strict;
use warnings;

my @fh;

my $file_name = $ARGV[0];
my $infile    = $ARGV[1];

#convert every 4-line fastq to 1-line
open(FH, "cat '$infile' | awk '{printf \"%s%s\",\$0,(NR%4?FS:RS)}' | ");

while (<FH>) {
  chomp;

  my @line = split(/\s+/, $_);
  my $len  = length($line[1]);

  if ($len >= 100) {

    #print $len,"\n",$_,"\n";
    push @fh, $len;

    if (not defined $fh[$len]) {
      open $fh[$len], '>', "$file_name\_$len";
    }
    print { $fh[$len] } (join("\n", @line), "\n");
  }

}

错误

Can't use string ("151") as a symbol ref while "strict refs" in use at

如何处理这些文件?

【问题讨论】:

  • push @fh, $len; 没有意义,因为您将纯标量存储到为文件句柄保留的数组中。
  • tnx.我刚刚删除它并工作!
  • @TahmtanEbrahimi 我更改了您帖子的标题,使其对未来的搜索更有意义和通用,并在测试正文中保留了错误消息。通常,标题不应过长或重复特定的错误消息或代码 - 相反,这些应该在您的帖子正文中。如果我的措辞有误,请进一步编辑标题,以便生物信息学家能够理解。
  • 虽然您在这里没有直接使用Bioperl 包,但为了相关性,我添加了这个标签。 BioPerl 发行版中包含的一些现有BioPerl scripts 可能对您工作的这方面或其他方面有所帮助。

标签: perl bioinformatics bioperl fastq sequencing


【解决方案1】:

正如您所读到的,您的问题是因为一个虚假的push@fh 数组的末尾添加了一个整数值。我假设您的目标是将数组扩展为足够长以添加新的文件句柄。你可以通过分配给$#fh来做到这一点,所以你会写$#fh = $len if $#fh &lt; $len;但是这是不必要的,因为当您简单地分配数组末尾的元素时,Perl 会自动为您扩展数组

我有几个关于你的程序的 cmets,希望对你有用

  • 使用 awk 命令是不必要且浪费的。 Perl 完全有能力做 awk 能做的所有事情

  • 如果你发现自己在写split /\s+/, $_,那么你几乎肯定是指split:默认行为是split ' ', $_。如果您使用/\s+/ 作为模式并且您要拆分的字符串恰好有前导空格,那么split 将返回一个空字符串作为字段列表中的第一项。如果您改用' '(文字上的单个空格,而不是/ / 模式),则不会发生这种情况。实际上,split ' ' 等价于 /\S+/g

  • 在字符串中插入变量值时,如果后面的字符可能是标识符的一部分,那么将标识符放在大括号内通常会更整洁。所以"${file_name}_$len" 而不是"$file_name\_$len"

这就是我编写代码的方式。它将输入记录累积到$line,直到添加了四个记录,然后像以前一样处理该行。

#!/usr/bin/perl

use strict;
use warnings;

my ($file_name, $infile) = @ARGV;

open my $in_fh, '<', $infile or die $!;
my $line;

my @fh;
while ( <$in_fh> ) {
  chomp;
  $line .= $_;

  if ( $. % 4 == 0 or eof ) {

    my @line = split ' ', $line;
    my $len  = length $line[1];
    next if $len < 100;

    open $fh[$len], '>', "${file_name}_$len" unless $fh[$len];
    print { $fh[$len] } "$_\n" for @line;

    $line = undef;
  }
}

【讨论】:

  • 非常感谢
  • 提示:我怀疑大多数人都知道eofeof() 是不同的,更不用说它们各自的作用了。最好使用eof($in_fh)
  • @ikegami:我认为让您的评论讲述自己的故事就足够了。对我来说这是一个设计错误,因为即使 eof()eof ARGV 是不同的
  • 当然,这是一个糟糕的设计。
【解决方案2】:

这个错误具体的意思是你正在做一些需要参考的事情,但它没有得到参考。

行:

print {$fh[$len]} (join("\n",@line),"\n");

显式打印到文件句柄 - 来自一个名为 @fh 的文件句柄列表。

这一行:

push @fh, $len;

将在该列表中插入一个数值。 (大概$line[1] 是 151 个字符长)。所以你实际上是在尝试:

 print {151} (join("\n",@line),"\n");

希望这很明显 - 只是行不通。您看起来像是在尝试打开文件句柄,并将其插入到数组中:

open $fh[$len], '>', "$file_name\_$len";

我是否可以建议您最好为此使用哈希?否则,您将得到一个充满空元素的数组,其中一个已填充。

你可以在哪里代替:

#further up:
my %fh; 


#and then
open ( $fh{$len}, ">", "$file_name\_$len" ) or warn $!; 

不要忘记在最后关闭文件句柄:

foreach my $key ( keys %fh ) {
   close ( $fh{$key} );
}

我也建议而不是:

open( FH, "cat '$infile' | awk '{printf \"%s%s\",\$0,(NR%4?FS:RS)}' | " );

您最好在 perl 中处理它,因为您所做的只是使用外部二进制文件解析文件。 (并使用词法文件句柄:`open ( $input, "-|, "cat '$infile' | awk '{printf \"%s%s\",\$0,(NR%4?FS:RS)}' " ) 或警告 $!; )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 2023-01-09
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    相关资源
    最近更新 更多