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 )