App-Egaz

 view release on metacpan or  search on metacpan

lib/App/Egaz/Command/lav2psl.pm  view on Meta::CPAN

        #----------------------------#
        # "<filename>[-]" <start> <stop> [<rev_comp_flag> <sequence_number>]
        $lav =~ /s \{\s+(.+?)\s+\}/s;
        my $s_stanza = $1;
        my @s_lines  = $s_stanza =~ /(.+ \s+ \d+ \s+ \d+ \s+ \d+ \s+ \d+)/gx;
        if ( scalar @s_lines != 2 ) {
            Carp::croak "s-stanza error.\n";
        }

        $s_lines[0] =~ /\s*\"?(.+?)\-?\"? \s+ (\d+) \s+ (\d+) \s+ (\d+) \s+ (\d+)/x;
        my ( $t_file, $t_seq_start, $t_seq_stop, $t_strand, $t_contig ) = ( $1, $2, $3, $4, $5 );
        if ( $t_seq_start != 1 ) {
            Carp::croak "Target sequence doesn't start at 1\n";
        }

        $s_lines[1] =~ /\s*\"?(.+?)\-?\"? \s+ (\d+) \s+ (\d+) \s+ (\d+) \s+ (\d+)/x;
        my ( $q_file, $q_seq_start, $q_seq_stop, $q_strand, $q_contig ) = ( $1, $2, $3, $4, $5 );
        if ( $q_seq_start != 1 ) {
            Carp::croak "Query sequence doesn't start at 1\n";
        }

        #----------------------------#
        # h-stanza
        #----------------------------#
        $lav =~ /h \{\s+(.+?)\s+\}/s;
        my $h_stanza = $1;
        my @h_lines  = $h_stanza =~ /(.+)/g;
        if ( scalar @h_lines != 2 ) {
            Carp::croak "h-stanza error.\n";
        }

        $h_lines[0] =~ m{">?\s*(\w+)};
        my $t_name = $1;

        $h_lines[1] =~ m{">?\s*(\w+)};
        my $q_name = $1;

        if ( $h_lines[1] =~ m{ \(reverse complement\)} ) {
            if ( $q_strand == 0 ) {
                Carp::croak "q_strand from h-stanza doesn't match with s-stanza.\n";
            }
        }

        #----------------------------#
        # generate psl lines
        #----------------------------#
        my @a_stanzas = $lav =~ /a \{\s+(.+?)\s+\}/sg;
        for my $a_stanza (@a_stanzas) {
            my ( $match, $mismatch ) = ( 0, 0, );
            my ( $q_num_ins, $q_base_ins, $t_num_ins, $t_base_ins, ) = ( 0, 0, 0, 0, );
            my ( @sizes, @q_begins, @t_begins );

            my @align_pieces = $a_stanza =~ /\s*l (\d+ \d+ \d+ \d+ \d+)/g;
            my $t_former_end;
            my $q_former_end;
            for my $align_piece (@align_pieces) {

                unless ( $align_piece =~ /(\d+) (\d+) (\d+) (\d+) (\d+)/g ) {
                    Carp::croak "l-line error\n";
                }
                my ( $t_begin, $q_begin, $t_end, $q_end, $percent_id ) = ( $1, $2, $3, $4, $5 );
                $t_begin--;
                $q_begin--;
                $percent_id = 0.01 * $percent_id;

                my $bases       = $q_end - $q_begin;
                my $match_piece = App::Egaz::Common::round( $percent_id * $bases );
                $match += $match_piece;
                $mismatch += $bases - $match_piece;

                if ( $t_former_end and $t_begin != $t_former_end ) {
                    $t_num_ins++;
                    $t_base_ins += $t_begin - $t_former_end;
                }
                if ( $q_former_end and $q_begin != $q_former_end ) {
                    $q_num_ins++;
                    $q_base_ins += $q_begin - $q_former_end;
                }
                $t_former_end = $t_end;
                $q_former_end = $q_end;

                push @sizes,    $t_end - $t_begin;
                push @q_begins, $q_begin;
                push @t_begins, $t_begin;
            }

            # b-line, begins
            unless ( $a_stanza =~ /\s*b (\d+) (\d+)/ ) {
                Carp::croak "No b-line.\n";
            }
            my $t_from = $1;
            my $q_from = $2;
            $t_from--;
            $q_from--;

            # e-line, ends
            unless ( $a_stanza =~ /\s*e (\d+) (\d+)/ ) {
                Carp::croak "No e-line.\n";
            }
            my $t_to = $1;
            my $q_to = $2;

            # s-line, scores
            unless ( $a_stanza =~ /\s*s (\d+)/ ) {
                Carp::croak "No s-line.\n";
            }
            my $score = $1;

            # prepare psl line
            my $psl_line;
            $psl_line .= sprintf "%d\t%d\t0\t0\t", $match, $mismatch;
            $psl_line .= sprintf "%d\t%d\t%d\t%d\t", $q_num_ins, $q_base_ins, $t_num_ins,
                $t_base_ins,;
            $psl_line .= sprintf "%s\t", $q_strand ? '-' : '+';

            # if query is - strand, convert begin/end to genomic coordinates
            if ($q_strand) {
                $psl_line .= sprintf "%s\t%d\t%d\t%d\t", $q_name, $q_seq_stop, $q_seq_stop - $q_to,
                    $q_seq_stop - $q_from;
            }
            else {
                $psl_line .= sprintf "%s\t%d\t%d\t%d\t", $q_name, $q_seq_stop, $q_from, $q_to;
            }

            $psl_line .= sprintf "%s\t%d\t%d\t%d\t", $t_name, $t_seq_stop, $t_from, $t_to;
            $psl_line .= sprintf "%d\t", scalar @align_pieces;



( run in 0.603 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )