我正在学习如何将perl用于基因组学应用。我正在尝试清理成对的结束读取(1个正向,1个反向)。它们存储在2个文件中,但行匹配。我正在做的就是从第二个文件中读取相关的子程序(我得到的警告是未初始化的值)。
这些文件设置为4个行块(fastq),其中第一行是运行ID,第二行是序列,第三行是“+”,第四行包含第2行中序列的质量值。 / p>
这个代码只应用于一个文件时没有真正的麻烦,但我想我误解了如何处理多个文件。
非常感谢任何指导!
我在这种情况下的警告是这样的:在./pairedendtrim.pl第137行第4行的减法( - )中使用未初始化的值$ thisline。
#!/usr/bin/perl
#pairedendtrim.pl by AHU
use strict;
use warnings;
die "usage: readtrimmer.pl <file1> <file2> <nthreshold> " unless @ARGV == 3;
my $nthreshold = "$ARGV[2]";
open( my $fastq1, "<", "$ARGV[0]" );
open( my $fastq2, "<", "$ARGV[1]" );
my @forline;
my @revline;
while ( not eof $fastq2 and not eof $fastq1 ) {
chomp $fastq1;
chomp $fastq2;
$forline[0] = <$fastq1>;
$forline[1] = <$fastq1>;
$forline[2] = <$fastq1>;
$forline[3] = <$fastq1>;
$revline[0] = <$fastq2>;
$revline[1] = <$fastq2>;
$revline[2] = <$fastq2>;
$revline[3] = <$fastq2>;
my $ncheckfor = removen( $forline[1] );
my $ncheckrev = removen( $revline[1] );
my $fortest = 0;
if ( $ncheckfor =~ /ok/ ) { $fortest = 1 }
my $revtest = 0;
if ( $ncheckrev =~ /ok/ ) { $revtest = 1 }
if ( $fortest == 1 and $revtest == 1 ) { print "READ 1 AND READ 2" }
if ( $fortest == 1 and $revtest == 0 ) { print "Read 1 only" }
if ( $fortest == 0 and $revtest == 1 ) { print "READ 2 only" }
}
sub removen {
my ($thisline) = $_;
my $ntotal = 0;
for ( my $i = 0; $i < length($thisline) - 1; $i++ ) {
my $pos = substr( $thisline, $i, 1 );
#print "$pos\n";
if ( $pos =~ /N/ ) { $ntotal++ }
}
my $nout;
if ( $ntotal <= $nthreshold ) #threshold for N
{
$nout = "ok";
} else {
$nout = "bad";
}
return ($nout);
}
答案 0 :(得分:0)
子程序的参数位于@_
,而不是$_
sub removen {
my ($thisline) = @_;
我还有一些其他提示:
use autodie;
只要您正在进行文件处理。@ARGV
中的值分配给变量。这很快就记录下了什么。chomp
文件句柄。这没有任何作用。而是将chomp
应用于从阅读中返回的值。ok
和bad
用作布尔值。tr
可用于计算字符在字符串中的次数。以下是代码的清理版本:
#!/usr/bin/perl
#pairedendtrim.pl by AHU
use strict;
use warnings;
use autodie;
die "usage: readtrimmer.pl <file1> <file2> <nthreshold> " unless @ARGV == 3;
my ( $file1, $file2, $nthreshold ) = @ARGV;
open my $fh1, '<', $file1;
open my $fh2, '<', $file2;
while ( not eof $fh2 and not eof $fh1 ) {
chomp( my @forline = map { scalar <$fh1> } ( 1 .. 4 ) );
chomp( my @revline = map { scalar <$fh2> } ( 1 .. 4 ) );
my $ncheckfor = removen( $forline[1] );
my $ncheckrev = removen( $revline[1] );
print "READ 1 AND READ 2" if $ncheckfor and $ncheckrev;
print "Read 1 only" if $ncheckfor and !$ncheckrev;
print "READ 2 only" if !$ncheckfor and $ncheckrev;
}
sub removen {
my ($thisline) = @_;
my $ntotal = $thisline =~ tr/N/N/;
return $ntotal <= $nthreshold; #threshold for N
}