-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNeedleman_Wunsch.pl
executable file
·112 lines (91 loc) · 2.46 KB
/
Needleman_Wunsch.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env perl
use strict;
use warnings;
my $seq1 = $ARGV[0];
my $seq2 = $ARGV[1];
if ( not $seq1 or not $seq2 ){
die "Must present two strings on command line";
}
my $gap_penalty = -1;
my $scoreMatrix;
my @lettersA = split //, $seq1;
my @lettersB = split //, $seq2;
# Fill out initial values
# Example:
# G C A T G C U
# 0 -1 -2 -3 -4 -5 -6 -7
# G -1
# A -2
# T -3
# T -4
# A -5
# C -6
# A -7
for ( my $i = 0 ; $i < length($seq1) + 1 ; $i++ ) {
$scoreMatrix->[$i][0] = $i * $gap_penalty;
}
for (my $i=0; $i < length($seq2) + 1; $i++) {
$scoreMatrix->[0][$i] = $i * $gap_penalty;
}
my $tracebackMatrix;
$tracebackMatrix->[0][0] = 'Diagonal';
for ( my $i = 1 ; $i < length($seq1) + 1 ; $i++ ) {
for ( my $j = 1 ; $j < length($seq2) + 1 ; $j++ ) {
no warnings;
# Diagonal
my $match =
$scoreMatrix->[ $i - 1 ][ $j - 1 ] +
score( $lettersA[ $i - 1 ], $lettersB[ $j - 1 ] );
# up
my $delete = $scoreMatrix->[ $i - 1 ][$j] + $gap_penalty;
# left
my $insert = $scoreMatrix->[$i][ $j - 1 ] + $gap_penalty;
my $max = max( $match, $delete, $insert );
my $whatMatched = '';
for ($max) {
$whatMatched = 'Left' if ( $_ eq $insert );
$whatMatched = 'Up' if ( $_ eq $delete );
$whatMatched = 'Diagonal' if ( $_ eq $match );
}
$scoreMatrix->[$i][$j] = $max;
$tracebackMatrix->[$i][$j] = $whatMatched;
}
}
my $alignA = '';
my $alignB = '';
my $i = length($seq1);
my $j = length($seq2);
while ( $i > 0 or $j > 0 ) {
no warnings;
if ( $i > 0 && $j > 0 && $tracebackMatrix->[$i][$j] eq 'Diagonal' ) {
$alignA = $lettersA[ $i - 1 ] . $alignA;
$alignB = $lettersB[ $j - 1 ] . $alignB;
$i--;
$j--;
}
elsif ( $i > 0 && $tracebackMatrix->[$i][$j] eq 'Up' ) {
$alignA = $lettersA[ $i - 1 ] . $alignA;
$alignB = '-' . $alignB;
$i--;
}
else {
$alignA = '-' . $alignA;
$alignB = $lettersB[ $j - 1 ] . $alignB;
$j--;
}
}
sub score {
my ( $letterA, $letterB ) = @_;
return -1 if ( scalar @_ < 2 ); #Only received one letter
return 1 if ( $letterA eq $letterB ); #Match
return -1 if ( $letterA ne $letterB ); # Mismatch
}
sub max {
my ( $max, @vars ) = @_;
for (@vars) {
$max = $_ if ( $_ > $max );
}
return $max;
}
print "Best alignment for $seq1: $alignA\n";
print "Best alignment for $seq2: $alignB\n";