Mercurial > repos > cpt > cpt_psm_plotter
view lib/CPT/Bio/NW_MSA.pm @ 1:8691c1c61a8e draft default tip
planemo upload commit 94b0cd1fff0826c6db3e7dc0c91c0c5a8be8bb0c
author | cpt |
---|---|
date | Mon, 05 Jun 2023 02:48:47 +0000 |
parents | |
children |
line wrap: on
line source
package CPT::Bio::NW_MSA; use Moose; use strict; use warnings; use autodie; use List::Util qw(max); has 'sequences' => ( is => 'rw', isa => 'ArrayRef'); # If true, relationships are assumed to be bidirectional has 'bidi' => (is => 'rw', isa => 'Bool'); has 'relationships' => ( is => 'rw', isa => 'HashRef', default => sub { {} }); # has 'verbose' => ( is => 'rw', isa => 'Num'); # has 'gap_penalty' => ( is => 'rw', isa => 'Num'); has 'match_score' => ( is => 'rw', isa => 'Num'); has 'mismatch_score' => ( is => 'rw', isa => 'Num'); # local stuff #has 'current_list' => ( is => 'rw', isa => 'ArrayRef'); has 'merger' => (is => 'rw', isa => 'HashRef'); has 'number_of_aligned_lists' => ( is => 'rw', isa => 'Num', default => sub { 0 }); sub add_relationship { my ($self, $from, $to) = @_; ${$self->relationships()}{$from}{$to} = 1; if($self->bidi()){ ${$self->relationships()}{$to}{$from} = 1; } } sub Sij { my($self, $merger_row, $query) = @_; # Comparing a query against a merger row my @check_against = @{$merger_row}; #print "Checking " . join(",",@check_against) .":$query\t"; foreach(@check_against){ if(${$self->relationships()}{$query}{$_} || ${$self->relationships()}{$_}{$query}){ #print $self->match_score() . "\n"; return $self->match_score(); } } #print $self->mismatch_score() . "\n"; return $self->mismatch_score(); } sub align_list { my ($self, $list_ref) = @_; # If we haven't aligned any lists, we do something special if($self->number_of_aligned_lists() == 0){ # Pretend we've aligned ONE list already $self->number_of_aligned_lists(1); my @list = @{$list_ref}; # Fake the merger my %merger; for(my $i = 0; $i < scalar @list; $i++){ $merger{$i} = [$list[$i]]; } $self->merger(\%merger); }else{ $self->find_best_path($self->merger(), $list_ref); $self->number_of_aligned_lists($self->number_of_aligned_lists() + 1); } } sub find_best_path { my ($self, $merger_ref, $list_ref) = @_; my %merger = %{$merger_ref}; my @list = @{$list_ref}; my $max_i = scalar(keys(%merger)); my $max_j = scalar(@list); my %score_mat; my %point_mat; # Initial zeros for matrices $point_mat{0}{0} = 'DONE'; $score_mat{0}{0} = 0; for(my $a = 1; $a <= $max_i; $a++){ $point_mat{$a}{0} = 'U'; $score_mat{$a}{0} = $self->gap_penalty(); } for(my $b = 1; $b <= $max_j; $b++){ $point_mat{0}{$b} = 'L'; $score_mat{0}{$b} = $self->gap_penalty(); } # Score for(my $i = 1 ; $i <= $max_i; $i++){ my $ci = $merger{$i-1}; for(my $j = 1; $j <= $max_j; $j++){ my $cj = $list[$j-1]; # Scoring my $diag_score = $score_mat{$i-1}{$j-1} + $self->Sij($ci,$cj); my $up_score = $score_mat{$i-1}{$j} + $self->gap_penalty(); my $left_score = $score_mat{$i}{$j-1} + $self->gap_penalty(); if($diag_score >= $up_score){ if($diag_score >= $left_score){ $score_mat{$i}{$j} = $diag_score; $point_mat{$i}{$j} = 'D'; }else{ $score_mat{$i}{$j} = $left_score; $point_mat{$i}{$j} = 'L'; } }else{ if($up_score >= $left_score){ $score_mat{$i}{$j} = $up_score; $point_mat{$i}{$j} = 'U'; }else{ $score_mat{$i}{$j} = $left_score; $point_mat{$i}{$j} = 'L'; } } } } $self->print2DArray('score_mat', \%score_mat); $self->print2DArray('point_mat', \%point_mat); # Calculate merger my @new_row_set; my $i = $max_i + 0; my $j = $max_j + 0; while($i != 0 || $j != 0){ my $dir = $point_mat{$i}{$j}; my @new_row; if($dir eq 'D'){ push(@new_row, @{$merger{$i-1}}, $list[$j-1]); $i--; $j--; }elsif($dir eq 'L'){ push(@new_row, split(//, '-' x ($self->number_of_aligned_lists()))); push(@new_row, $list[$j-1]); $j--; }elsif($dir eq 'U'){ push(@new_row, @{$merger{$i-1}}, '-'); $i--; } if($self->verbose()){ print join("\t", $i, $j, $dir, @new_row),"\n"; } push(@new_row_set,\@new_row); } my %new_merger; for(my $i = 0; $i < scalar(@new_row_set); $i++){ $new_merger{$i} = $new_row_set[scalar(@new_row_set) - $i - 1]; } $self->merger(\%new_merger); } sub merged_array{ my ($self) = @_; my %m = %{$self->merger()}; my @result; foreach(sort{$a<=>$b} keys(%m)){ push(@result, $m{$_}); } return @result; } sub print2DArray{ my($self,$name, $ref) = @_; if($self->verbose && defined $ref){ print '*' x 32,"\n"; print $name,"\n"; if(ref $ref eq 'ARRAY'){ foreach(@{$ref}){ print join("\t",@{$_}),"\n"; } }elsif(ref $ref eq 'HASH'){ my %h = %{$ref}; foreach my $a(sort(keys(%h))){ if(ref $h{$a} eq 'ARRAY'){ print join("", map { sprintf "%-4s",$_ } @{$h{$a}}); }else{ foreach my $b(sort(keys($h{$a}))){ if(defined($h{$a}{$b})){ printf "%5s", $h{$a}{$b}; } } } print "\n"; } }else{ die 'Unsupported'; } print '*' x 32,"\n"; } } no Moose; 1; __END__ =pod =encoding UTF-8 =head1 NAME CPT::Bio::NW_MSA =head1 VERSION version 1.99.4 =head1 AUTHOR Eric Rasche <rasche.eric@yandex.ru> =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2014 by Eric Rasche. This is free software, licensed under: The GNU General Public License, Version 3, June 2007 =cut