App-Fasops
view release on metacpan or search on metacpan
lib/App/Fasops/Command/refine.pm view on Meta::CPAN
}
for my $i ( 0 .. scalar @{$seq_refs} - 1 ) {
$info_ary->[$i]{seq} = uc $seq_refs->[$i];
}
}
#----------------------------#
# change headers
#----------------------------#
if ( $opt->{chop} ) {
trim_head_tail( $info_ary, $opt->{chop} );
}
my $out_string;
for my $info ( @{$info_ary} ) {
$out_string .= sprintf ">%s\n", App::RL::Common::encode_header($info);
$out_string .= sprintf "%s\n", $info->{seq};
}
$out_string .= "\n";
return $out_string;
}
#----------------------------#
# trim head and tail indels
#----------------------------#
# If head length set to 1, the first indel will be trimmed
# Length set to 5 and the second indel will also be trimmed
# GAAA--C...
# --AAAGC...
# GAAAAGC...
sub trim_head_tail {
my $info_ary = shift;
my $chop_length = shift; # indels in this region will also be trimmed
# default value means only trimming indels starting at the first base
$chop_length = defined $chop_length ? $chop_length : 1;
my $align_length = length $info_ary->[0]{seq};
# chop region covers all
return if $chop_length * 2 >= $align_length;
my $indel_set = AlignDB::IntSpan->new;
for my $info ( @{$info_ary} ) {
my $seq_indel_set = App::Fasops::Common::indel_intspan( $info->{seq} );
$indel_set->merge($seq_indel_set);
}
# There're no indels at all
# Leave $info_ary untouched
return if $indel_set->is_empty;
{ # head indel(s) to be trimmed
my $head_set = AlignDB::IntSpan->new;
$head_set->add_pair( 1, $chop_length );
my $head_indel_set = $indel_set->find_islands($head_set);
# head indels
if ( $head_indel_set->is_not_empty ) {
for ( 1 .. $head_indel_set->max ) {
for my $info ( @{$info_ary} ) {
my $base = substr( $info->{seq}, 0, 1, '' );
if ( $base ne '-' ) {
if ( $info->{strand} eq "+" ) {
$info->{start}++;
}
else {
$info->{end}--;
}
}
}
}
}
}
{ # tail indel(s) to be trimmed
my $tail_set = AlignDB::IntSpan->new;
$tail_set->add_range( $align_length - $chop_length + 1, $align_length );
my $tail_indel_set = $indel_set->find_islands($tail_set);
# tail indels
if ( $tail_indel_set->is_not_empty ) {
for ( $tail_indel_set->min .. $align_length ) {
for my $info ( @{$info_ary} ) {
my $base = substr( $info->{seq}, -1, 1, '' );
if ( $base ne '-' ) {
if ( $info->{strand} eq "+" ) {
$info->{end}--;
}
else {
$info->{start}++;
}
}
}
}
}
}
}
1;
( run in 1.157 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )