~ubuntu-branches/ubuntu/trusty/bioperl/trusty

« back to all changes in this revision

Viewing changes to scripts/utilities/revtrans-motif.PLS

  • Committer: Package Import Robot
  • Author(s): Charles Plessy
  • Date: 2013-09-22 13:39:48 UTC
  • mfrom: (3.1.11 sid)
  • Revision ID: package-import@ubuntu.com-20130922133948-c6z62zegjyp7ztou
Tags: 1.6.922-1
* New upstream release.
* Replaces and Breaks grinder (<< 0.5.3-3~) because of overlaping contents.
  Closes: #722910
* Stop Replacing and Breaking bioperl ( << 1.6.9 ): not needed anymore. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/perl
2
 
use warnings;
3
 
use strict;
4
 
 
5
 
use Bio::Seq;
6
 
use Bio::Tools::CodonTable;
7
 
 
8
 
use List::MoreUtils qw(uniq);
9
 
use Carp qw(croak);
10
 
 
11
 
use Getopt::Long;
12
 
use Pod::Usage;
13
 
 
14
 
=head1 NAME
15
 
 
16
 
revtrans-motif - Reverse translate a Profam-like protein motif
17
 
 
18
 
=head1 VERSION
19
 
 
20
 
Version 0.01
21
 
 
22
 
=cut
23
 
 
24
 
our $VERSION = '0.01';
25
 
 
26
 
=head1 SYNOPSIS
27
 
 
28
 
From a file:
29
 
 
30
 
    revtrans-motif.pl -i motifs.txt
31
 
 
32
 
Using pipes:
33
 
 
34
 
   revtrans-motif.pl < motifs.txt > output.txt
35
 
 
36
 
Using interactively at the command prompt:
37
 
 
38
 
   $ revtrans-motif.pl
39
 
   MAAEEL[VIKP]
40
 
   1.   ATGGCNGCNGARGARYTNVHN
41
 
   [^P]H(IW){2,3}
42
 
   2.   NDNCAY(ATHTGG){2,3}
43
 
 
44
 
=cut
45
 
 
46
 
# File IO, default to STDIN.
47
 
my ($help, $infile);
48
 
GetOptions( "h|help" => \$help, "i|infile:s" => \$infile );
49
 
 
50
 
# Parse command line arguments.
51
 
unless (defined $infile) { $infile = '-' };
52
 
open( my $fh, "<$infile" ) or die "Couldn't open file $infile: $!\n";
53
 
 
54
 
if ($help) { pod2usage(-verbose => 3) };
55
 
 
56
 
# Process each line, output to STDOUT.
57
 
while (my $motif = <$fh>) {
58
 
   if ($motif =~ /^\s*#/) { next }; # Ignore comments.
59
 
   chomp $motif;
60
 
   my $line = $.;
61
 
 
62
 
   my $result;
63
 
   eval { $result = reverse_translate_motif($motif) };
64
 
   if ($@) { warn $@; next }
65
 
 
66
 
   print $line, ".\t", $result, "\n";
67
 
}
68
 
 
69
 
sub reverse_translate_motif {
70
 
   # Main subroutine. It takes a Profam-like motif and returns its
71
 
   # reverse translation using degenerate codons.
72
 
 
73
 
   # Steps:
74
 
   # 1. Tokenize, then parse tokens.
75
 
   # 2. Reverse translate each token type.
76
 
   # 3. Join tokens in original order. Return the resulting string.
77
 
 
78
 
   my $motif = shift;
79
 
 
80
 
   $motif =~ s/\./X/g;
81
 
   $motif = uc $motif;
82
 
 
83
 
   ### 1. Tokenize, parse the motif.
84
 
   my ( $ordered, $classified ) = parse_motif($motif);
85
 
 
86
 
   ### 2. Reverse translate each token type.
87
 
   # Reverse translate the plain (unambiguous) tokens.
88
 
   my $ct = Bio::Tools::CodonTable->new;
89
 
   foreach my $seq ( @{ $classified->{plain} } ) {
90
 
      my $seqO
91
 
          = Bio::Seq->new( -seq => $$seq, -alphabet => 'protein' );
92
 
      $$seq = $ct->reverse_translate_all($seqO);
93
 
   }
94
 
 
95
 
   # Reverse translate the ambiguous tokens.
96
 
   foreach my $token ( @{ $classified->{ambiguous} } ) {
97
 
      my ($aas) = $$token =~ m(([A-Za-z\.]+));
98
 
      my @codons_to_contract;
99
 
 
100
 
      foreach my $residue ( split '', $aas ) {
101
 
         push @codons_to_contract, $ct->revtranslate($residue);
102
 
      }
103
 
 
104
 
      my $ambiguous_codon = contract_codons(@codons_to_contract);
105
 
      $$token             = $ambiguous_codon;
106
 
   }
107
 
 
108
 
   # Reverse translate the negated residues.
109
 
   foreach my $token ( @{ $classified->{negated} } ) {
110
 
      my ($aas) = $$token =~ m(([A-Za-z\.]+));
111
 
      my $ambiguous_codon = negated_aas_to_codon($aas);
112
 
      $$token = $ambiguous_codon;
113
 
   }
114
 
 
115
 
   ### 3. Join the profile back from its tokens.
116
 
   return join '', map {$$_} @{$ordered};
117
 
 
118
 
}
119
 
 
120
 
sub parse_motif {
121
 
   # Profam-like motif parser. It takes the pattern as a string, and
122
 
   # returns two data structures that contain the tokens, organized
123
 
   # by order of appearance in the pattern (first return value) and by
124
 
   # category (second return value).
125
 
 
126
 
   my $motif = shift;
127
 
   my $parser  = tokenize_motif($motif);
128
 
   my ( %tokens, @tokens );
129
 
 
130
 
   while ( my $token = $parser->() ) {
131
 
      croak "Unknown syntax token: <", $token->[1], ">"
132
 
          if ( $token->[0] eq 'UNKNOWN' );
133
 
      push @{ $tokens{ $token->[0] } }, \$token->[1];
134
 
      push @tokens, \$token->[1];
135
 
   }
136
 
   return ( \@tokens, \%tokens );
137
 
}
138
 
 
139
 
sub tokenize_motif {
140
 
 
141
 
   # Return a tokenizer iterator that sequentially recognizes and
142
 
   # returns each token in the input pattern.
143
 
   # Examples of each token type:
144
 
 
145
 
   # ambiguous: a position with more than one possible residue.
146
 
   #     eg. [ALEP]
147
 
   # negated: a position in which some residues are excluded.
148
 
   #     eg. [^WY]
149
 
   # plain: a common sequence of residues. One position, one residue.
150
 
   #     eg. MAAEIK
151
 
   # open_par, close_par: tags surrounding a motif that is repeated
152
 
   #     a certain number of times.
153
 
   #     eg. (...){3}
154
 
 
155
 
   my $target = shift;
156
 
   return sub {
157
 
      return [ 'ambiguous', $1 ]
158
 
          if $target =~ /\G (\[[A-Za-z\.]+\])     /gcx;
159
 
      return [ 'negated',   $1 ]
160
 
          if $target =~ /\G (\[\^[A-Za-z\.]+\])   /gcx;
161
 
      return [ 'plain',     $1 ]
162
 
          if $target =~ /\G ([A-Za-z\.]+)         /gcx;
163
 
      return [ 'open_par',  $1 ]
164
 
          if $target =~ /\G (\()                  /gcx;
165
 
      return [ 'close_par', $1 ]
166
 
          if $target =~ /\G (\)[\{\d+[,\d+]*\}]*) /gcx;
167
 
      return [ 'UNKNOWN',   $1 ]
168
 
          if $target =~ /\G (.)                   /gcx;
169
 
      return;
170
 
   };
171
 
}
172
 
 
173
 
sub contract_codons {
174
 
 
175
 
   # Take a list of codons, return an ambiguous codon.
176
 
   my @codons = map { uc $_ } @_;
177
 
 
178
 
   my @by_letter = ( [], [], [], );
179
 
   my $ambiguous_codon;
180
 
   foreach my $codon (@codons) {
181
 
      my @letters = split '', $codon;
182
 
      for my $i ( 0 .. 2 ) {
183
 
         push @{ $by_letter[$i] }, $letters[$i];
184
 
      }
185
 
   }
186
 
   for my $i ( 0 .. 2 ) {
187
 
      $ambiguous_codon
188
 
          .= convert( 'dna', uniq_string( @{ $by_letter[$i] } ) );
189
 
   }
190
 
   return $ambiguous_codon;
191
 
}
192
 
 
193
 
sub expand_codon {
194
 
 
195
 
   # Given a degenerate codon, return a list with all its
196
 
   # constituents. Takes a three-letter string (codon) as
197
 
   # input, returns a list with three-letter scalars.
198
 
 
199
 
   my $codon = shift;
200
 
   die "Wrong codon length!\n" if length $codon != 3;
201
 
 
202
 
 
203
 
   my ( @codons, @return_bases );
204
 
   my @orig_bases = split '', $codon;
205
 
 
206
 
   for my $i ( 0 .. 2 ) {
207
 
 
208
 
      # from each redundant base, create a list with all their
209
 
      # components (e.g., N -> (A, C, G, T) );
210
 
      my @components = split '', convert('dna', $orig_bases[$i] );
211
 
      $orig_bases[$i] = [@components];
212
 
   }
213
 
 
214
 
   # Combine all the bases of each of the three positions of the
215
 
   # codons, and build the return list.
216
 
   for my $i ( @{ $orig_bases[0] } ) {
217
 
      for my $j ( @{ $orig_bases[1] } ) {
218
 
         for my $k ( @{ $orig_bases[2] } ) {
219
 
            push @return_bases, $i . $j . $k;
220
 
         }
221
 
      }
222
 
   }
223
 
   return @return_bases;
224
 
}
225
 
 
226
 
{
227
 
   my %convert;
228
 
 
229
 
   sub convert {
230
 
      # Interconvert between redundant and non-redundant protein and
231
 
      # dna alphabets. Takes an alphabet (protein or dna) and a string
232
 
      # with the letter, and returns its equivalent in
233
 
      # redundant/non-redundant alphabet. Example ACTG -> N.
234
 
 
235
 
      my ($alphabet, $letter) = @_;
236
 
      unless (
237
 
         $alphabet and $alphabet =~ /^dna$|^protein$/i
238
 
         and $letter and length $letter <= 4
239
 
      ) { croak "Wrong arguments!\n"; }
240
 
 
241
 
      unless (%convert) {
242
 
         %convert = (
243
 
            'dna' => {
244
 
               qw(N ACGT B CGT D AGT H ACT V ACG K GT
245
 
                   M AC R AG S CG W AT Y CT A A C C T T G G)
246
 
            },
247
 
            'protein' => {
248
 
               '.' => 'ACDEFGHIJKLMNOPQRSTUVWY',
249
 
               X   => 'ACDEFGHIJKLMNOPQRSTUVWY',
250
 
               Z   => 'QE',
251
 
               B   => 'ND',
252
 
            },
253
 
         );
254
 
 
255
 
         # Make %convert hash key/value agnostic.
256
 
         foreach my $alphabet ( keys %convert ) {
257
 
            map { $convert{$alphabet}->{ $convert{$alphabet}{$_} } = $_ }
258
 
                keys %{ $convert{$alphabet} };
259
 
         }
260
 
      }
261
 
 
262
 
      return $convert{$alphabet}{$letter};
263
 
   }
264
 
 
265
 
}
266
 
 
267
 
sub uniq_string {
268
 
   # Takes a list of letters and returns an alphabetically sorted
269
 
   # list with unique elements.
270
 
 
271
 
   my @letters = @_;
272
 
   return join '', sort { $a cmp $b } uniq @letters;
273
 
}
274
 
 
275
 
{
276
 
   my ( @codon_library, $ct );
277
 
 
278
 
   sub negated_aas_to_codon {
279
 
 
280
 
      # Given a string of residues, returns a degenerate codon that will
281
 
      # not be translated into any of them, while maximizing degeneracy
282
 
      # (ie, it tries to also translate into as many residues as possible).
283
 
 
284
 
      # This functionality is required for reverse translating profiles
285
 
      # that contain negative patterns: [^X]. This means that the current
286
 
      # position should not contain aminoacid X, but can have any of the
287
 
      # others. The reverse translated nucleotide sequence should
288
 
      # reflect this.
289
 
 
290
 
      # Approach: construct a list of all possible codons, incluiding all
291
 
      # degenerate bases. This is an array of 15x15x15 = 3375 elements.
292
 
      # Order them by descendent "degeneracy".
293
 
      # Return the first one whose expansion in 4-lettered codons
294
 
      # doesn't contain a codon that translates into any of the
295
 
      # non-wanted residues.
296
 
      
297
 
      # * Since this takes some time, I presorted them and saved them.
298
 
      # Reading them from a file takes a fraction of the time that it taes
299
 
      # to re-sort them every time the application is launched.
300
 
 
301
 
      my $aas_to_avoid = shift;
302
 
 
303
 
      # Initialize reusable variables if it's the first time the sub
304
 
      # is called.
305
 
      unless (@codon_library) {
306
 
         while (<DATA>) { chomp; push @codon_library, split ' ', $_ }
307
 
      }
308
 
      unless ($ct) { $ct = Bio::Tools::CodonTable->new; }
309
 
 
310
 
      # Reverse translate the unwanted aminoacids to unwanted codons.
311
 
      my @unwanted_codons;
312
 
      foreach my $aa ( split '', $aas_to_avoid ) {
313
 
         push @unwanted_codons, $ct->revtranslate($aa);
314
 
      }
315
 
 
316
 
      foreach my $degenerate_codon (@codon_library) {
317
 
         my @codons  = expand_codon($degenerate_codon);
318
 
         my $success = 1;
319
 
 
320
 
         foreach my $unwanted (@unwanted_codons) {
321
 
            if ( grep { uc $unwanted eq $_ } @codons ) {
322
 
               $success = 0;
323
 
            }
324
 
         }
325
 
 
326
 
         if ($success) { return $degenerate_codon }
327
 
      }
328
 
   }
329
 
 
330
 
}
331
 
 
332
 
=head1 DESCRIPTION
333
 
 
334
 
This script takes a protein motif as input and returns a degenerate
335
 
oligonucleotide sequence corresponding to it. The main reason for doing this
336
 
is to design degenerate primers that amplify a given sequence pattern.
337
 
 
338
 
The input motif consists of a string of one-letter residues, with any of
339
 
the following syntactic elements:
340
 
 
341
 
=over 4
342
 
 
343
 
=item B<[...]> : Redundant position.
344
 
 
345
 
A position in which more than one residue is allowed. Example: 
346
 
 
347
 
    [TS]YW[RKSD]
348
 
     ^^    ^^^^
349
 
 
350
 
=item B<[^...]> : Negated position.
351
 
 
352
 
A position in which any residue is allowed, saved for those between
353
 
brackets. Example:
354
 
 
355
 
    [^PW]MK[LAE]
356
 
      ^^
357
 
 
358
 
=item B<(...){n,m,...}> : Repeated motif.
359
 
 
360
 
A motif that is repeated B<n> or B<m> times. It can have any of the previous
361
 
syntactic elements. Example:
362
 
 
363
 
    A[SN]C(TXX){2,4,8}
364
 
           ^^^
365
 
 
366
 
=back
367
 
 
368
 
The allowed letters are those that correspond to the 20 natural aminoacids,
369
 
plus:
370
 
 
371
 
    B = N + D
372
 
    Z = Q + E
373
 
    X = All
374
 
 
375
 
=head1 OPTIONS
376
 
 
377
 
=head2 B<-i input-file>:
378
 
 
379
 
A file with a list of motifs to reverse translate.
380
 
 
381
 
=head2 B<-h>
382
 
 
383
 
Display this help message.
384
 
 
385
 
=cut
386
 
 
387
 
=head1 AUTHOR
388
 
 
389
 
Bruno Vecchi, C<vecchi.b at gmail.com>
390
 
 
391
 
=head1 BUGS
392
 
 
393
 
Please report any bugs or feature requests to C<vecchi.b at gmail.com>
394
 
 
395
 
=head1 COPYRIGHT & LICENSE
396
 
 
397
 
Copyright 2009 Bruno Vecchi, all rights reserved.
398
 
 
399
 
This program is free software; you can redistribute it and/or modify it
400
 
under the same terms as Perl itself.
401
 
 
402
 
 
403
 
=cut
404
 
 
405
 
__DATA__
406
 
NNN NNB NND NNH NNV NBN NDN NHN NVN BNN DNN HNN VNN NBB NBD NBH NBV NDB NDD
407
 
NDH NDV NHB NHD NHH NHV NVB NVD NVH NVV BNB BND BNH BNV BBN BDN BHN BVN DNB
408
 
DND DNH DNV DBN DDN DHN DVN HNB HND HNH HNV HBN HDN HHN HVN VNB VND VNH VNV
409
 
VBN VDN VHN VVN NNK NNM NNR NNS NNW NNY NKN NMN NRN NSN NWN NYN KNN MNN RNN
410
 
SNN WNN YNN BBB BBD BBH BBV BDB BDD BDH BDV BHB BHD BHH BHV BVB BVD BVH BVV
411
 
DBB DBD DBH DBV DDB DDD DDH DDV DHB DHD DHH DHV DVB DVD DVH DVV HBB HBD HBH
412
 
HBV HDB HDD HDH HDV HHB HHD HHH HHV HVB HVD HVH HVV VBB VBD VBH VBV VDB VDD
413
 
VDH VDV VHB VHD VHH VHV VVB VVD VVH VVV NBK NBM NBR NBS NBW NBY NDK NDM NDR
414
 
NDS NDW NDY NHK NHM NHR NHS NHW NHY NVK NVM NVR NVS NVW NVY NKB NKD NKH NKV
415
 
NMB NMD NMH NMV NRB NRD NRH NRV NSB NSD NSH NSV NWB NWD NWH NWV NYB NYD NYH
416
 
NYV BNK BNM BNR BNS BNW BNY BKN BMN BRN BSN BWN BYN DNK DNM DNR DNS DNW DNY
417
 
DKN DMN DRN DSN DWN DYN HNK HNM HNR HNS HNW HNY HKN HMN HRN HSN HWN HYN VNK
418
 
VNM VNR VNS VNW VNY VKN VMN VRN VSN VWN VYN KNB KND KNH KNV KBN KDN KHN KVN
419
 
MNB MND MNH MNV MBN MDN MHN MVN RNB RND RNH RNV RBN RDN RHN RVN SNB SND SNH
420
 
SNV SBN SDN SHN SVN WNB WND WNH WNV WBN WDN WHN WVN YNB YND YNH YNV YBN YDN
421
 
YHN YVN BBK BBM BBR BBS BBW BBY BDK BDM BDR BDS BDW BDY BHK BHM BHR BHS BHW
422
 
BHY BVK BVM BVR BVS BVW BVY BKB BKD BKH BKV BMB BMD BMH BMV BRB BRD BRH BRV
423
 
BSB BSD BSH BSV BWB BWD BWH BWV BYB BYD BYH BYV DBK DBM DBR DBS DBW DBY DDK
424
 
DDM DDR DDS DDW DDY DHK DHM DHR DHS DHW DHY DVK DVM DVR DVS DVW DVY DKB DKD
425
 
DKH DKV DMB DMD DMH DMV DRB DRD DRH DRV DSB DSD DSH DSV DWB DWD DWH DWV DYB
426
 
DYD DYH DYV HBK HBM HBR HBS HBW HBY HDK HDM HDR HDS HDW HDY HHK HHM HHR HHS
427
 
HHW HHY HVK HVM HVR HVS HVW HVY HKB HKD HKH HKV HMB HMD HMH HMV HRB HRD HRH
428
 
HRV HSB HSD HSH HSV HWB HWD HWH HWV HYB HYD HYH HYV VBK VBM VBR VBS VBW VBY
429
 
VDK VDM VDR VDS VDW VDY VHK VHM VHR VHS VHW VHY VVK VVM VVR VVS VVW VVY VKB
430
 
VKD VKH VKV VMB VMD VMH VMV VRB VRD VRH VRV VSB VSD VSH VSV VWB VWD VWH VWV
431
 
VYB VYD VYH VYV KBB KBD KBH KBV KDB KDD KDH KDV KHB KHD KHH KHV KVB KVD KVH
432
 
KVV MBB MBD MBH MBV MDB MDD MDH MDV MHB MHD MHH MHV MVB MVD MVH MVV RBB RBD
433
 
RBH RBV RDB RDD RDH RDV RHB RHD RHH RHV RVB RVD RVH RVV SBB SBD SBH SBV SDB
434
 
SDD SDH SDV SHB SHD SHH SHV SVB SVD SVH SVV WBB WBD WBH WBV WDB WDD WDH WDV
435
 
WHB WHD WHH WHV WVB WVD WVH WVV YBB YBD YBH YBV YDB YDD YDH YDV YHB YHD YHH
436
 
YHV YVB YVD YVH YVV NNA NNC NNT NNG NKK NKM NKR NKS NKW NKY NMK NMM NMR NMS
437
 
NMW NMY NRK NRM NRR NRS NRW NRY NSK NSM NSR NSS NSW NSY NWK NWM NWR NWS NWW
438
 
NWY NYK NYM NYR NYS NYW NYY NAN NCN NTN NGN KNK KNM KNR KNS KNW KNY KKN KMN
439
 
KRN KSN KWN KYN MNK MNM MNR MNS MNW MNY MKN MMN MRN MSN MWN MYN RNK RNM RNR
440
 
RNS RNW RNY RKN RMN RRN RSN RWN RYN SNK SNM SNR SNS SNW SNY SKN SMN SRN SSN
441
 
SWN SYN WNK WNM WNR WNS WNW WNY WKN WMN WRN WSN WWN WYN YNK YNM YNR YNS YNW
442
 
YNY YKN YMN YRN YSN YWN YYN ANN CNN TNN GNN NBA NBC NBT NBG NDA NDC NDT NDG
443
 
NHA NHC NHT NHG NVA NVC NVT NVG NAB NAD NAH NAV NCB NCD NCH NCV NTB NTD NTH
444
 
NTV NGB NGD NGH NGV BNA BNC BNT BNG BKK BKM BKR BKS BKW BKY BMK BMM BMR BMS
445
 
BMW BMY BRK BRM BRR BRS BRW BRY BSK BSM BSR BSS BSW BSY BWK BWM BWR BWS BWW
446
 
BWY BYK BYM BYR BYS BYW BYY BAN BCN BTN BGN DNA DNC DNT DNG DKK DKM DKR DKS
447
 
DKW DKY DMK DMM DMR DMS DMW DMY DRK DRM DRR DRS DRW DRY DSK DSM DSR DSS DSW
448
 
DSY DWK DWM DWR DWS DWW DWY DYK DYM DYR DYS DYW DYY DAN DCN DTN DGN HNA HNC
449
 
HNT HNG HKK HKM HKR HKS HKW HKY HMK HMM HMR HMS HMW HMY HRK HRM HRR HRS HRW
450
 
HRY HSK HSM HSR HSS HSW HSY HWK HWM HWR HWS HWW HWY HYK HYM HYR HYS HYW HYY
451
 
HAN HCN HTN HGN VNA VNC VNT VNG VKK VKM VKR VKS VKW VKY VMK VMM VMR VMS VMW
452
 
VMY VRK VRM VRR VRS VRW VRY VSK VSM VSR VSS VSW VSY VWK VWM VWR VWS VWW VWY
453
 
VYK VYM VYR VYS VYW VYY VAN VCN VTN VGN KBK KBM KBR KBS KBW KBY KDK KDM KDR
454
 
KDS KDW KDY KHK KHM KHR KHS KHW KHY KVK KVM KVR KVS KVW KVY KKB KKD KKH KKV
455
 
KMB KMD KMH KMV KRB KRD KRH KRV KSB KSD KSH KSV KWB KWD KWH KWV KYB KYD KYH
456
 
KYV MBK MBM MBR MBS MBW MBY MDK MDM MDR MDS MDW MDY MHK MHM MHR MHS MHW MHY
457
 
MVK MVM MVR MVS MVW MVY MKB MKD MKH MKV MMB MMD MMH MMV MRB MRD MRH MRV MSB
458
 
MSD MSH MSV MWB MWD MWH MWV MYB MYD MYH MYV RBK RBM RBR RBS RBW RBY RDK RDM
459
 
RDR RDS RDW RDY RHK RHM RHR RHS RHW RHY RVK RVM RVR RVS RVW RVY RKB RKD RKH
460
 
RKV RMB RMD RMH RMV RRB RRD RRH RRV RSB RSD RSH RSV RWB RWD RWH RWV RYB RYD
461
 
RYH RYV SBK SBM SBR SBS SBW SBY SDK SDM SDR SDS SDW SDY SHK SHM SHR SHS SHW
462
 
SHY SVK SVM SVR SVS SVW SVY SKB SKD SKH SKV SMB SMD SMH SMV SRB SRD SRH SRV
463
 
SSB SSD SSH SSV SWB SWD SWH SWV SYB SYD SYH SYV WBK WBM WBR WBS WBW WBY WDK
464
 
WDM WDR WDS WDW WDY WHK WHM WHR WHS WHW WHY WVK WVM WVR WVS WVW WVY WKB WKD
465
 
WKH WKV WMB WMD WMH WMV WRB WRD WRH WRV WSB WSD WSH WSV WWB WWD WWH WWV WYB
466
 
WYD WYH WYV YBK YBM YBR YBS YBW YBY YDK YDM YDR YDS YDW YDY YHK YHM YHR YHS
467
 
YHW YHY YVK YVM YVR YVS YVW YVY YKB YKD YKH YKV YMB YMD YMH YMV YRB YRD YRH
468
 
YRV YSB YSD YSH YSV YWB YWD YWH YWV YYB YYD YYH YYV ANB AND ANH ANV ABN ADN
469
 
AHN AVN CNB CND CNH CNV CBN CDN CHN CVN TNB TND TNH TNV TBN TDN THN TVN GNB
470
 
GND GNH GNV GBN GDN GHN GVN BBA BBC BBT BBG BDA BDC BDT BDG BHA BHC BHT BHG
471
 
BVA BVC BVT BVG BAB BAD BAH BAV BCB BCD BCH BCV BTB BTD BTH BTV BGB BGD BGH
472
 
BGV DBA DBC DBT DBG DDA DDC DDT DDG DHA DHC DHT DHG DVA DVC DVT DVG DAB DAD
473
 
DAH DAV DCB DCD DCH DCV DTB DTD DTH DTV DGB DGD DGH DGV HBA HBC HBT HBG HDA
474
 
HDC HDT HDG HHA HHC HHT HHG HVA HVC HVT HVG HAB HAD HAH HAV HCB HCD HCH HCV
475
 
HTB HTD HTH HTV HGB HGD HGH HGV VBA VBC VBT VBG VDA VDC VDT VDG VHA VHC VHT
476
 
VHG VVA VVC VVT VVG VAB VAD VAH VAV VCB VCD VCH VCV VTB VTD VTH VTV VGB VGD
477
 
VGH VGV ABB ABD ABH ABV ADB ADD ADH ADV AHB AHD AHH AHV AVB AVD AVH AVV CBB
478
 
CBD CBH CBV CDB CDD CDH CDV CHB CHD CHH CHV CVB CVD CVH CVV TBB TBD TBH TBV
479
 
TDB TDD TDH TDV THB THD THH THV TVB TVD TVH TVV GBB GBD GBH GBV GDB GDD GDH
480
 
GDV GHB GHD GHH GHV GVB GVD GVH GVV NKA NKC NKT NKG NMA NMC NMT NMG NRA NRC
481
 
NRT NRG NSA NSC NST NSG NWA NWC NWT NWG NYA NYC NYT NYG NAK NAM NAR NAS NAW
482
 
NAY NCK NCM NCR NCS NCW NCY NTK NTM NTR NTS NTW NTY NGK NGM NGR NGS NGW NGY
483
 
KNA KNC KNT KNG KKK KKM KKR KKS KKW KKY KMK KMM KMR KMS KMW KMY KRK KRM KRR
484
 
KRS KRW KRY KSK KSM KSR KSS KSW KSY KWK KWM KWR KWS KWW KWY KYK KYM KYR KYS
485
 
KYW KYY KAN KCN KTN KGN MNA MNC MNT MNG MKK MKM MKR MKS MKW MKY MMK MMM MMR
486
 
MMS MMW MMY MRK MRM MRR MRS MRW MRY MSK MSM MSR MSS MSW MSY MWK MWM MWR MWS
487
 
MWW MWY MYK MYM MYR MYS MYW MYY MAN MCN MTN MGN RNA RNC RNT RNG RKK RKM RKR
488
 
RKS RKW RKY RMK RMM RMR RMS RMW RMY RRK RRM RRR RRS RRW RRY RSK RSM RSR RSS
489
 
RSW RSY RWK RWM RWR RWS RWW RWY RYK RYM RYR RYS RYW RYY RAN RCN RTN RGN SNA
490
 
SNC SNT SNG SKK SKM SKR SKS SKW SKY SMK SMM SMR SMS SMW SMY SRK SRM SRR SRS
491
 
SRW SRY SSK SSM SSR SSS SSW SSY SWK SWM SWR SWS SWW SWY SYK SYM SYR SYS SYW
492
 
SYY SAN SCN STN SGN WNA WNC WNT WNG WKK WKM WKR WKS WKW WKY WMK WMM WMR WMS
493
 
WMW WMY WRK WRM WRR WRS WRW WRY WSK WSM WSR WSS WSW WSY WWK WWM WWR WWS WWW
494
 
WWY WYK WYM WYR WYS WYW WYY WAN WCN WTN WGN YNA YNC YNT YNG YKK YKM YKR YKS
495
 
YKW YKY YMK YMM YMR YMS YMW YMY YRK YRM YRR YRS YRW YRY YSK YSM YSR YSS YSW
496
 
YSY YWK YWM YWR YWS YWW YWY YYK YYM YYR YYS YYW YYY YAN YCN YTN YGN ANK ANM
497
 
ANR ANS ANW ANY AKN AMN ARN ASN AWN AYN CNK CNM CNR CNS CNW CNY CKN CMN CRN
498
 
CSN CWN CYN TNK TNM TNR TNS TNW TNY TKN TMN TRN TSN TWN TYN GNK GNM GNR GNS
499
 
GNW GNY GKN GMN GRN GSN GWN GYN BKA BKC BKT BKG BMA BMC BMT BMG BRA BRC BRT
500
 
BRG BSA BSC BST BSG BWA BWC BWT BWG BYA BYC BYT BYG BAK BAM BAR BAS BAW BAY
501
 
BCK BCM BCR BCS BCW BCY BTK BTM BTR BTS BTW BTY BGK BGM BGR BGS BGW BGY DKA
502
 
DKC DKT DKG DMA DMC DMT DMG DRA DRC DRT DRG DSA DSC DST DSG DWA DWC DWT DWG
503
 
DYA DYC DYT DYG DAK DAM DAR DAS DAW DAY DCK DCM DCR DCS DCW DCY DTK DTM DTR
504
 
DTS DTW DTY DGK DGM DGR DGS DGW DGY HKA HKC HKT HKG HMA HMC HMT HMG HRA HRC
505
 
HRT HRG HSA HSC HST HSG HWA HWC HWT HWG HYA HYC HYT HYG HAK HAM HAR HAS HAW
506
 
HAY HCK HCM HCR HCS HCW HCY HTK HTM HTR HTS HTW HTY HGK HGM HGR HGS HGW HGY
507
 
VKA VKC VKT VKG VMA VMC VMT VMG VRA VRC VRT VRG VSA VSC VST VSG VWA VWC VWT
508
 
VWG VYA VYC VYT VYG VAK VAM VAR VAS VAW VAY VCK VCM VCR VCS VCW VCY VTK VTM
509
 
VTR VTS VTW VTY VGK VGM VGR VGS VGW VGY KBA KBC KBT KBG KDA KDC KDT KDG KHA
510
 
KHC KHT KHG KVA KVC KVT KVG KAB KAD KAH KAV KCB KCD KCH KCV KTB KTD KTH KTV
511
 
KGB KGD KGH KGV MBA MBC MBT MBG MDA MDC MDT MDG MHA MHC MHT MHG MVA MVC MVT
512
 
MVG MAB MAD MAH MAV MCB MCD MCH MCV MTB MTD MTH MTV MGB MGD MGH MGV RBA RBC
513
 
RBT RBG RDA RDC RDT RDG RHA RHC RHT RHG RVA RVC RVT RVG RAB RAD RAH RAV RCB
514
 
RCD RCH RCV RTB RTD RTH RTV RGB RGD RGH RGV SBA SBC SBT SBG SDA SDC SDT SDG
515
 
SHA SHC SHT SHG SVA SVC SVT SVG SAB SAD SAH SAV SCB SCD SCH SCV STB STD STH
516
 
STV SGB SGD SGH SGV WBA WBC WBT WBG WDA WDC WDT WDG WHA WHC WHT WHG WVA WVC
517
 
WVT WVG WAB WAD WAH WAV WCB WCD WCH WCV WTB WTD WTH WTV WGB WGD WGH WGV YBA
518
 
YBC YBT YBG YDA YDC YDT YDG YHA YHC YHT YHG YVA YVC YVT YVG YAB YAD YAH YAV
519
 
YCB YCD YCH YCV YTB YTD YTH YTV YGB YGD YGH YGV ABK ABM ABR ABS ABW ABY ADK
520
 
ADM ADR ADS ADW ADY AHK AHM AHR AHS AHW AHY AVK AVM AVR AVS AVW AVY AKB AKD
521
 
AKH AKV AMB AMD AMH AMV ARB ARD ARH ARV ASB ASD ASH ASV AWB AWD AWH AWV AYB
522
 
AYD AYH AYV CBK CBM CBR CBS CBW CBY CDK CDM CDR CDS CDW CDY CHK CHM CHR CHS
523
 
CHW CHY CVK CVM CVR CVS CVW CVY CKB CKD CKH CKV CMB CMD CMH CMV CRB CRD CRH
524
 
CRV CSB CSD CSH CSV CWB CWD CWH CWV CYB CYD CYH CYV TBK TBM TBR TBS TBW TBY
525
 
TDK TDM TDR TDS TDW TDY THK THM THR THS THW THY TVK TVM TVR TVS TVW TVY TKB
526
 
TKD TKH TKV TMB TMD TMH TMV TRB TRD TRH TRV TSB TSD TSH TSV TWB TWD TWH TWV
527
 
TYB TYD TYH TYV GBK GBM GBR GBS GBW GBY GDK GDM GDR GDS GDW GDY GHK GHM GHR
528
 
GHS GHW GHY GVK GVM GVR GVS GVW GVY GKB GKD GKH GKV GMB GMD GMH GMV GRB GRD
529
 
GRH GRV GSB GSD GSH GSV GWB GWD GWH GWV GYB GYD GYH GYV NAA NAC NAT NAG NCA
530
 
NCC NCT NCG NTA NTC NTT NTG NGA NGC NGT NGG KKA KKC KKT KKG KMA KMC KMT KMG
531
 
KRA KRC KRT KRG KSA KSC KST KSG KWA KWC KWT KWG KYA KYC KYT KYG KAK KAM KAR
532
 
KAS KAW KAY KCK KCM KCR KCS KCW KCY KTK KTM KTR KTS KTW KTY KGK KGM KGR KGS
533
 
KGW KGY MKA MKC MKT MKG MMA MMC MMT MMG MRA MRC MRT MRG MSA MSC MST MSG MWA
534
 
MWC MWT MWG MYA MYC MYT MYG MAK MAM MAR MAS MAW MAY MCK MCM MCR MCS MCW MCY
535
 
MTK MTM MTR MTS MTW MTY MGK MGM MGR MGS MGW MGY RKA RKC RKT RKG RMA RMC RMT
536
 
RMG RRA RRC RRT RRG RSA RSC RST RSG RWA RWC RWT RWG RYA RYC RYT RYG RAK RAM
537
 
RAR RAS RAW RAY RCK RCM RCR RCS RCW RCY RTK RTM RTR RTS RTW RTY RGK RGM RGR
538
 
RGS RGW RGY SKA SKC SKT SKG SMA SMC SMT SMG SRA SRC SRT SRG SSA SSC SST SSG
539
 
SWA SWC SWT SWG SYA SYC SYT SYG SAK SAM SAR SAS SAW SAY SCK SCM SCR SCS SCW
540
 
SCY STK STM STR STS STW STY SGK SGM SGR SGS SGW SGY WKA WKC WKT WKG WMA WMC
541
 
WMT WMG WRA WRC WRT WRG WSA WSC WST WSG WWA WWC WWT WWG WYA WYC WYT WYG WAK
542
 
WAM WAR WAS WAW WAY WCK WCM WCR WCS WCW WCY WTK WTM WTR WTS WTW WTY WGK WGM
543
 
WGR WGS WGW WGY YKA YKC YKT YKG YMA YMC YMT YMG YRA YRC YRT YRG YSA YSC YST
544
 
YSG YWA YWC YWT YWG YYA YYC YYT YYG YAK YAM YAR YAS YAW YAY YCK YCM YCR YCS
545
 
YCW YCY YTK YTM YTR YTS YTW YTY YGK YGM YGR YGS YGW YGY ANA ANC ANT ANG AKK
546
 
AKM AKR AKS AKW AKY AMK AMM AMR AMS AMW AMY ARK ARM ARR ARS ARW ARY ASK ASM
547
 
ASR ASS ASW ASY AWK AWM AWR AWS AWW AWY AYK AYM AYR AYS AYW AYY AAN ACN ATN
548
 
AGN CNA CNC CNT CNG CKK CKM CKR CKS CKW CKY CMK CMM CMR CMS CMW CMY CRK CRM
549
 
CRR CRS CRW CRY CSK CSM CSR CSS CSW CSY CWK CWM CWR CWS CWW CWY CYK CYM CYR
550
 
CYS CYW CYY CAN CCN CTN CGN TNA TNC TNT TNG TKK TKM TKR TKS TKW TKY TMK TMM
551
 
TMR TMS TMW TMY TRK TRM TRR TRS TRW TRY TSK TSM TSR TSS TSW TSY TWK TWM TWR
552
 
TWS TWW TWY TYK TYM TYR TYS TYW TYY TAN TCN TTN TGN GNA GNC GNT GNG GKK GKM
553
 
GKR GKS GKW GKY GMK GMM GMR GMS GMW GMY GRK GRM GRR GRS GRW GRY GSK GSM GSR
554
 
GSS GSW GSY GWK GWM GWR GWS GWW GWY GYK GYM GYR GYS GYW GYY GAN GCN GTN GGN
555
 
BAA BAC BAT BAG BCA BCC BCT BCG BTA BTC BTT BTG BGA BGC BGT BGG DAA DAC DAT
556
 
DAG DCA DCC DCT DCG DTA DTC DTT DTG DGA DGC DGT DGG HAA HAC HAT HAG HCA HCC
557
 
HCT HCG HTA HTC HTT HTG HGA HGC HGT HGG VAA VAC VAT VAG VCA VCC VCT VCG VTA
558
 
VTC VTT VTG VGA VGC VGT VGG ABA ABC ABT ABG ADA ADC ADT ADG AHA AHC AHT AHG
559
 
AVA AVC AVT AVG AAB AAD AAH AAV ACB ACD ACH ACV ATB ATD ATH ATV AGB AGD AGH
560
 
AGV CBA CBC CBT CBG CDA CDC CDT CDG CHA CHC CHT CHG CVA CVC CVT CVG CAB CAD
561
 
CAH CAV CCB CCD CCH CCV CTB CTD CTH CTV CGB CGD CGH CGV TBA TBC TBT TBG TDA
562
 
TDC TDT TDG THA THC THT THG TVA TVC TVT TVG TAB TAD TAH TAV TCB TCD TCH TCV
563
 
TTB TTD TTH TTV TGB TGD TGH TGV GBA GBC GBT GBG GDA GDC GDT GDG GHA GHC GHT
564
 
GHG GVA GVC GVT GVG GAB GAD GAH GAV GCB GCD GCH GCV GTB GTD GTH GTV GGB GGD
565
 
GGH GGV KAA KAC KAT KAG KCA KCC KCT KCG KTA KTC KTT KTG KGA KGC KGT KGG MAA
566
 
MAC MAT MAG MCA MCC MCT MCG MTA MTC MTT MTG MGA MGC MGT MGG RAA RAC RAT RAG
567
 
RCA RCC RCT RCG RTA RTC RTT RTG RGA RGC RGT RGG SAA SAC SAT SAG SCA SCC SCT
568
 
SCG STA STC STT STG SGA SGC SGT SGG WAA WAC WAT WAG WCA WCC WCT WCG WTA WTC
569
 
WTT WTG WGA WGC WGT WGG YAA YAC YAT YAG YCA YCC YCT YCG YTA YTC YTT YTG YGA
570
 
YGC YGT YGG AKA AKC AKT AKG AMA AMC AMT AMG ARA ARC ART ARG ASA ASC AST ASG
571
 
AWA AWC AWT AWG AYA AYC AYT AYG AAK AAM AAR AAS AAW AAY ACK ACM ACR ACS ACW
572
 
ACY ATK ATM ATR ATS ATW ATY AGK AGM AGR AGS AGW AGY CKA CKC CKT CKG CMA CMC
573
 
CMT CMG CRA CRC CRT CRG CSA CSC CST CSG CWA CWC CWT CWG CYA CYC CYT CYG CAK
574
 
CAM CAR CAS CAW CAY CCK CCM CCR CCS CCW CCY CTK CTM CTR CTS CTW CTY CGK CGM
575
 
CGR CGS CGW CGY TKA TKC TKT TKG TMA TMC TMT TMG TRA TRC TRT TRG TSA TSC TST
576
 
TSG TWA TWC TWT TWG TYA TYC TYT TYG TAK TAM TAR TAS TAW TAY TCK TCM TCR TCS
577
 
TCW TCY TTK TTM TTR TTS TTW TTY TGK TGM TGR TGS TGW TGY GKA GKC GKT GKG GMA
578
 
GMC GMT GMG GRA GRC GRT GRG GSA GSC GST GSG GWA GWC GWT GWG GYA GYC GYT GYG
579
 
GAK GAM GAR GAS GAW GAY GCK GCM GCR GCS GCW GCY GTK GTM GTR GTS GTW GTY GGK
580
 
GGM GGR GGS GGW GGY AAA AAC AAT AAG ACA ACC ACT ACG ATA ATC ATT ATG AGA AGC
581
 
AGT AGG CAA CAC CAT CAG CCA CCC CCT CCG CTA CTC CTT CTG CGA CGC CGT CGG TAA
582
 
TAC TAT TAG TCA TCC TCT TCG TTA TTC TTT TTG TGA TGC TGT TGG GAA GAC GAT GAG
583
 
GCA GCC GCT GCG GTA GTC GTT GTG GGA GGC GGT GGG