File Coverage

blib/lib/Bio/Translator/Table.pm
Criterion Covered Total %
statement 202 207 97.5
branch 36 44 81.8
condition 12 18 66.6
subroutine 21 22 95.4
pod 4 4 100.0
total 275 295 93.2


line stmt bran cond sub pod time code
1             package Bio::Translator::Table;
2              
3 9     9   51 use strict;
  9         22  
  9         311  
4 9     9   42 use warnings;
  9         16  
  9         276  
5              
6             =head1 NAME
7              
8             Bio::Translator::Table - translation table
9              
10             =head1 SYNOPSIS
11              
12             use Bio::Translator::Table;
13            
14             my $table = new Bio::Translator();
15             my $table = new Bio::Translator(11);
16             my $table = new Bio::Translator( 12, { type => 'id' } );
17             my $table = new Bio::Translator( 'Yeast Mitochondrial', { type => 'name' } );
18             my $table = new Bio::Translator( 'mito', { type => 'name' } );
19              
20             my $table = custom Bio::Translator( \$custom_table );
21             my $tale = custom Bio::Translator( \$custom_table, { bootstrap => 0 } );
22              
23              
24             =cut
25              
26 9     9   46 use base qw(Class::Accessor::Fast);
  9         15  
  9         1020  
27             __PACKAGE__->mk_accessors(qw(id names codon2aa codon2start aa2codons));
28              
29 9     9   45 use Params::Validate;
  9         17  
  9         424  
30 9     9   41 use Carp;
  9         16  
  9         587  
31              
32 9         2063 use Bio::Util::DNA qw(
33             %degenerate2nucleotides
34             %nucleotides2degenerate
35             %degenerate_hierarchy
36              
37             $degenerate_match
38              
39             @DNAs
40              
41             @all_nucleotides
42             $all_nucleotide_match
43              
44             unrollDNA
45             reverse_complement
46 9     9   6002 );
  9         11079  
47              
48 9         24505 use Bio::Util::AA qw(
49             %ambiguous_forward
50             %ambiguous_map
51             $aa_match
52 9     9   8503 );
  9         12327  
53              
54             our $DEFAULT_ID = 1;
55             our $DEFAULT_TYPE = 'id';
56             our $DEFAULT_BOOTSTRAP = 1;
57              
58             =head1 CONSTRUCTORS
59              
60             =cut
61              
62             # helper constructor
63             sub _new {
64             shift->SUPER::new(
65             {
66 8     8   102 names => [],
67             codon2aa => Bio::Translator::Table::Pair->new(),
68             codon2start => Bio::Translator::Table::Pair->new(),
69             aa2codons => Bio::Translator::Table::Pair->new()
70             }
71             );
72             }
73              
74             =head2 new
75              
76             my $table = Bio::Translator::Table->new();
77             my $table = Bio::Translator::Table->new( $id );
78             my $table = Bio::Translator::Table->new( $id, \%params );
79              
80             This method creates a translation table by loading a table string from the
81             internal list. Pass an ID and the type of ID. By default, it will load the
82             translation table with id 1. The type of ID may be "id" or "name," which
83             correspond to the numeric id of the translation table or the long name of the
84             translation table. For instance, below are the headers for the first 3 table
85             strings.
86              
87             {
88             name "Standard" ,
89             name "SGC0" ,
90             id 1 ,
91             ...
92             },
93             {
94             name "Vertebrate Mitochondrial" ,
95             name "SGC1" ,
96             id 2 ,
97             ...
98             },
99             {
100             name "Yeast Mitochondrial" ,
101             name "SGC2" ,
102             id 3 ,
103             ...
104             },
105             ...
106              
107             By default, the "Standard" translation table will be loaded. You may instantiate
108             this translation table by calling any of the following:
109              
110             my $t = Bio::Translator::Table->new();
111             my $t = Bio::Translator::Table->new(1);
112             my $t = Bio::Translator::Table->new( 1, { type => 'id' } );
113             my $t = Bio::Translator::Table->new( 'Standard', { type => 'name' } );
114             my $t = Bio::Translator::Table->new( 'SGC0', { type => 'name' } );
115             my $t = Bio::Translator::Table->new( 'standard', { type => 'name' } );
116             my $t = Bio::Translator::Table->new( 'stan', { type => 'name' } );
117              
118             For partial matches, this module will use the first matching translation
119             table.
120              
121             my $t = Bio::Translator::Table->new( 'mitochondrial', { type => 'name' } );
122              
123             This will use translation table with ID 2, "Vertebrate Mitochondrial," because
124             that is the first match (even though "Yeast Mitochondrial" would also match).
125              
126             =cut
127              
128             sub new {
129 7     7 1 19 my $class = shift;
130              
131 7         15 my ( $id, @p );
132              
133             # id has a default, but if supplied, must be a scalar
134 7         236 ( $id, $p[0] ) = validate_pos(
135             @_,
136             { type => Params::Validate::SCALAR, default => $DEFAULT_ID },
137             { type => Params::Validate::HASHREF, default => {} }
138             );
139              
140             # type must be either id or name
141 7         203 my %p = validate(
142             @p,
143             {
144             type => {
145             default => $DEFAULT_TYPE,
146             regex => qr/id|name/
147             }
148             }
149             );
150              
151             # Get the beginning DATA so that we can seek back to it
152 7         61 my $start_pos = tell DATA;
153              
154             # Set up regular expression for searching.
155 7 50       176 my $match = ( $p{type} eq 'id' ) ? qr/id $id\b/ : qr/name ".*$id.*"/i;
156              
157             # Go through every internal table until it matches on id or name.
158 7         21 my $found = 0;
159 7         38 local $/ = "}";
160 7         14 local $_;
161 7         72 while () {
162 7 50       81 if ( $_ =~ $match ) {
163 7         19 $found = 1;
164 7         14 last;
165             }
166             }
167              
168             # Reset DATA
169 7         80 seek DATA, $start_pos, 0;
170              
171             # Call custom with internal table. We don't want to bootstrap.
172 7 50       84 return $class->custom( \$_, { bootstrap => 0 } ) if ($found);
173              
174             # Internal table not matched.
175 0         0 carp("Table with $p{type} of $id not found");
176 0         0 return;
177             }
178              
179             =head2 custom()
180              
181             my $table = Bio::Translator::Table->custom( $table_ref );
182             my $table = Bio::Translator::Table->custom( $table_ref, \%params );
183              
184             Create a translation table based off a passed table reference for custom
185             translation tables. Loads degenerate nucleotides if bootstrap isn't set (this
186             can take a little time). The format of the translation table should reflect
187             those of the internal tables:
188              
189             name "Names separated; by semicolons"
190             name "May have multiple lines"
191             id 99
192             ncbieaa "AMINOACIDS...",
193             sncbieaa "-M--------..."
194             -- Base1 AAAAAAAAAA...
195             -- Base2 AAAACCCCGG...
196             -- Base3 ACGTACTGAC...
197              
198             Examples:
199              
200             $translator = new Translator(
201             table_ref => \'name "All Alanines; All the Time"
202             id 9000
203             ncbieaa "AAAAAAAA"
204             sncbieaa "----M---"
205             base1 AAAAAAAA
206             base2 AACCGGTT
207             base3 ACACACAC'
208             );
209              
210             $translator = new Translator(
211             table_ref => \$table,
212             bootstrap => 0
213             );
214              
215             =cut
216              
217             # Regular expression which should match translation tables and also extracts
218             # relevant information.
219             my $TABLE_REGEX = qr/
220             ( (?:name\s+".+?".*?) + )
221             (?:id\s+(\d+).*)?
222             ncbieaa\s+"([a-z*]+)".*
223             sncbieaa\s+"([a-z-]+)".*
224             base1\s+([a-z]+).*
225             base2\s+([a-z]+).*
226             base3\s+([a-z]+).*
227             /isx;
228              
229             sub custom {
230 8     8 1 22 my $class = shift;
231              
232 8         19 my ( $table_ref, @p );
233              
234             # table_ref is required and must be a refrerence to a scalar
235 8         261 ( $table_ref, $p[0] ) = validate_pos(
236             @_,
237             { type => Params::Validate::SCALARREF | Params::Validate::SCALAR },
238             { type => Params::Validate::HASHREF, default => {} }
239             );
240              
241 8 50       59 $table_ref = \$table_ref unless ( ref $table_ref );
242              
243             # get the bootstrap parameter
244 8         183 my %p = validate(
245             @p,
246             {
247             bootstrap => {
248             default => $DEFAULT_BOOTSTRAP,
249             regex => qr/^[01]$/
250             }
251             }
252             );
253              
254             # Match the table or return undef.
255 8 50 0     511 my ( $names, $id, $residues, $starts, @bases ) =
256             ( $$table_ref =~ $TABLE_REGEX )
257             or ( carp('Translation table is in invalid format') && return );
258              
259 8         57 my $self = $class->_new();
260              
261 8         158 $self->id($id);
262              
263             # get names from name string
264 8         68 @{ $self->names } = grep { $_ } map {
  16         43  
  16         52  
265 9         62 s/^\s+//;
266 16         33 s/\s+$//;
267 16         43 s/\n/ /g;
268 16         28 s/\s{2,}/ /g;
269 16         36 $_
270 8         166 } map { split /;/ } ( $names =~ /"(.+?)"/gis );
271              
272             # Get all the table pairs so we don't have to keep using accessors
273 8         89 my $codon2aa = $self->codon2aa;
274 8         62 my $codon2start = $self->codon2start;
275 8         141 my $aa2codons = $self->aa2codons;
276              
277             # Chop is used to efficiently get the last character from each string
278 8         100 while ( my $residue = uc( chop $residues ) ) {
279 274         576 my $start = uc( chop $starts );
280              
281             # get the possible nucleotides each position in the codon
282 822         991 my @nucleotides = map {
283 274         351 my $base = chop;
284             [
285 231         866 $base,
286              
287             # append degenerates
288             (
289             $degenerate2nucleotides{$base}
290 84         453 ? @{ $degenerate2nucleotides{$base} }
291             : ()
292             ),
293             (
294             $degenerate_hierarchy{$base}
295 822 100       3151 ? @{ $degenerate_hierarchy{$base} }
    100          
296             : ()
297             )
298             ]
299             } @bases;
300              
301             # Add each potential codon to the translation table
302 274         355 foreach my $base1 ( @{ $nucleotides[0] } ) {
  274         626  
303 414         445 foreach my $base2 ( @{ $nucleotides[1] } ) {
  414         671  
304 442         430 foreach my $base3 ( @{ $nucleotides[2] } ) {
  442         613  
305 1716         5162 my $codon = join( '', $base1, $base2, $base3 );
306              
307 1716         1947 my $reverse = ${ reverse_complement( \$codon ) };
  1716         4488  
308              
309             # If the residue is valid, store it
310 1716 100       12210 if ( $residue ne 'X' ) {
311 1667         3355 $codon2aa->store( $residue, $codon, $reverse );
312 1667         3106 $aa2codons->push( $residue, $codon, $reverse );
313             }
314              
315             # If the start is valid, store it
316 1716 100       6322 if ( ( $start ne '-' ) ) {
317 52         112 $codon2start->store( $start, $codon, $reverse );
318 52         106 $aa2codons->push( '+', $codon, $reverse );
319             }
320             }
321             }
322             }
323             }
324              
325             # Bootstrap the translation table
326 8 100       45 $self->bootstrap() if ( $p{bootstrap} );
327              
328 8         213 return $self;
329             }
330              
331             =head1 METHODS
332              
333             =cut
334              
335             =head2 add_translation
336              
337             $translator->add_translation( $codon, $residue );
338             $translator->add_translation( $codon, $residue, \%params );
339              
340             Add a codon-to-residue translation to the translation table. $start inidicates
341             if this is a start codon.
342              
343             Examples:
344              
345             # THESE AREN'T REAL!!!
346             $translator->add_translation( 'ABA', 'G' );
347             $translator->add_translation( 'ABA', 'M', { start => 1, strand => -1 } );
348              
349             =cut
350              
351             sub add_translation {
352 131     131 1 138 my $self = shift;
353              
354 131         2533 my ( $codon, $residue, @p ) = validate_pos(
355             @_,
356             { regex => qr/^${all_nucleotide_match}{3}$/ },
357             { regex => qr/^$aa_match$/ },
358             { type => Params::Validate::HASHREF, default => {} }
359             );
360              
361 131         4462 my %p = validate(
362             @p,
363             {
364             strand => {
365             default => 1,
366             regex => qr/^[+-]?1$/,
367             type => Params::Validate::SCALAR
368             },
369             start => {
370             default => 0,
371             regex => qr/^[01]$/,
372             type => Params::Validate::SCALAR
373             }
374             }
375             );
376              
377 131 50       996 my ( $codon_ref, $rc_codon_ref ) =
378             ( $p{strand} == 1 )
379             ? ( \$codon, reverse_complement( \$codon ) )
380             : ( reverse_complement( \$codon ), \$codon );
381              
382             # Store residue in the starts or regular translation table.
383 131 100       898 my $table = $p{start} ? 'codon2start' : 'codon2aa';
384 131         349 $table = $self->$table;
385              
386 131         696 $table->store( $residue, $$codon_ref, $$rc_codon_ref );
387              
388             # Store the reverse lookup
389 131 100       274 $residue = '+' if ( $p{start} );
390 131         313 $self->aa2codons->push( $residue, $$codon_ref, $$rc_codon_ref );
391             }
392              
393             =head2 bootstrap
394              
395             $translator->bootstrap();
396              
397             Bootstrap the translation table. Find every possible translation, even those
398             that involve degenerate nucleotides or ambiguous amino acids.
399              
400             =cut
401              
402             sub bootstrap {
403 2     2   4 my $self = shift;
404              
405             # Loop through every nucleotide combination and run _translate_codon on
406             # each.
407 2         4 foreach my $n1 (@all_nucleotides) {
408 32         56 foreach my $n2 (@all_nucleotides) {
409 512         730 foreach my $n3 (@all_nucleotides) {
410 8192         24868 $self->_unroll( $n1 . $n2 . $n3, $self->codon2aa->[0] );
411 8192         31641 $self->_unroll(
412             $n1 . $n2 . $n3,
413             $self->codon2start->[0],
414             { start => 1 }
415             );
416             }
417             }
418             }
419             }
420              
421             # This is the helper function for bootstrap. Handles codons with degenerate
422             # nucleotides: [RYMKWS] [BDHV] or N. Several codons may map to the same amino
423             # acid. If all possible codons for an amibguity map to the same residue, store
424             # that residue.
425              
426             sub _unroll {
427 56171     56171   137077 my $self = shift;
428 56171         64928 my $codon = shift;
429 56171         52413 my $table = shift;
430              
431             # Return the codon if we have it
432 56171 100       130275 return $table->{$codon} if ( $table->{$codon} );
433              
434             # Check for base case: no degenerate nucleotides; we can't unroll further.
435 41745 100       172149 return unless ( $codon =~ /($degenerate_match)/ );
436              
437 32125         30153 my $consensus;
438 32125         44142 my $nuc = $1;
439              
440             # Replace the nucleotide with every possiblity from degenerate map hash.
441 32125         30238 foreach ( @{ $degenerate2nucleotides{$nuc} } ) {
  32125         61353  
442 39787         41439 my $new_codon = $codon;
443 39787         233176 $new_codon =~ s/$nuc/$_/;
444              
445             # Recursively call this function
446 39787         92308 my $residue = $self->_unroll( $new_codon, $table, @_ );
447              
448             # If the new_codon didn't come to a consensus, or if the translation
449             # isn't defined for new_codon in a custom translation table, return
450             # undef.
451 39787 100       103476 return unless ( defined $residue );
452              
453             # If consensus isn't set, set it to the current residue.
454 14161 100       25907 $consensus = $residue unless ($consensus);
455              
456             # This is an interesting step. If the residue isn't the same as the
457             # consensus, check to see if they map to the same ambiguous amino acid.
458             # If true, then change the consensus to that ambiguous acid and proceed.
459             # Otherwise, return undef (consensus could not be reached).
460 14161 100       30308 if ( $residue ne $consensus ) {
461 6466 100 100     23071 if (
      100        
462             ( defined $ambiguous_forward{$residue} )
463             && ( defined $ambiguous_forward{$consensus} )
464             && ( $ambiguous_forward{$residue} eq
465             $ambiguous_forward{$consensus} )
466             )
467             {
468 98         222 $consensus = $ambiguous_forward{$consensus};
469             }
470             else {
471 6368         13470 return;
472             }
473             }
474             }
475              
476             # If we got this far, it means that we have a valid consensus sequence for
477             # a degenerate-nucleotide-containing codon. Cache and return results.
478 131         278 $self->add_translation( $codon, $consensus, @_ );
479 131         248 return $consensus;
480             }
481              
482             =head2 string
483              
484             my $table_string_ref = $translator->string();
485             my $table_string_ref = $translator->string( \%params );
486              
487             Returns the table string. %params can specify whether or not this table should
488             try to bootstrap itself using the bootstrap function above. By default, it will
489             try to.
490              
491             Examples:
492              
493             my $table_string_ref = $translator->string();
494             my $table_string_ref = $translator->string( { bootstrap => 0 } );
495              
496             =cut
497              
498             sub string {
499 1     1 1 496 my $self = shift;
500              
501 1         16 my $bootstrap =
502             validate_pos( @_,
503             { default => $DEFAULT_BOOTSTRAP, regex => qr/^[01]$/ } );
504              
505             # Bootstrap if necessary
506 1 50       8 $self->bootstrap() if ($bootstrap);
507              
508             # Generate the names string
509 1         3 my $names = join( '; ', @{ $self->names } );
  1         8  
510              
511             # Make the hashes of amino acid to codons and start amino acids to codons
512 1         11 my %aa2codons = %{ $self->aa2codons->forward };
  1         6  
513              
514 1         7 my $codon2start = $self->codon2start->forward;
515 1         3 my %start2codons;
516              
517 1         2 foreach my $start_codon ( @{ $aa2codons{'+'} } ) {
  1         4  
518 7         9 my $start_aa = $codon2start->{$start_codon};
519 7         8 push @{ $start2codons{$start_aa} }, $start_codon;
  7         20  
520             }
521              
522 1         5 delete $aa2codons{'+'};
523              
524             # Minimize the codons in each group by removing those that are implied by
525             # a degenerate codon
526 1         5 foreach my $group ( values(%aa2codons), values(%start2codons) ) {
527 25         47 my %group_hash = map { $_ => undef } @$group;
  198         358  
528 25         59 foreach my $codon (@$group) {
529 198         478 my $possibilities = unrollDNA( \$codon );
530 198         13398 shift(@$possibilities);
531 198         523 delete @group_hash{@$possibilities};
532             }
533 25         118 @$group = sort keys %group_hash;
534             }
535              
536             # Create the arrays that will be used to generate the string
537 1         3 my ( @residues, @starts );
538 1         3 my @bases = map { [] } (undef) x 3;
  3         7  
539              
540 1         3 foreach my $start ( sort keys %start2codons ) {
541 1         2 foreach my $codon ( @{ $start2codons{$start} } ) {
  1         3  
542 1         3 push @residues, 'X';
543 1         2 push @starts, $start;
544 1         4 for my $i ( 1 .. 3 ) { push @{ $bases[ -$i ] }, chop $codon }
  3         4  
  3         13  
545             }
546             }
547 1         12 foreach my $aa ( sort keys %aa2codons ) {
548 24 100       55 next if ( $ambiguous_map{$aa} );
549 21         20 foreach my $codon ( @{ $aa2codons{$aa} } ) {
  21         38  
550 25         40 push @residues, $aa;
551 25         26 push @starts, '-';
552 25         33 for my $i ( 1 .. 3 ) { push @{ $bases[ -$i ] }, chop $codon }
  75         67  
  75         189  
553             }
554             }
555 1         7 foreach my $aa ( sort keys %ambiguous_map ) {
556 3 50       10 my $group = $aa2codons{$aa} or next;
557 3         4 foreach my $codon (@$group) {
558 4         7 push @residues, $aa;
559 4         6 push @starts, '-';
560 4         7 for my $i ( 1 .. 3 ) { push @{ $bases[ -$i ] }, chop $codon }
  12         12  
  12         32  
561             }
562             }
563              
564             # Generate the string
565 3         19 my $string = join(
566             "\n", '{',
567             qq{name "$names" ,},
568             'id ' . $self->id . ' ,',
569             'ncbieaa "' . join( '', @residues ) . '",',
570             'sncbieaa "' . join( '', @starts ) . '",',
571 1         9 map( { "-- Base$_ " . join( '', @{ $bases[ $_ - 1 ] } ) . '"' }
  3         18  
572             ( 1 .. 3 ) ),
573             '}'
574             );
575              
576 1         23 return \$string;
577             }
578              
579             {
580              
581             package Bio::Translator::Table::Pair;
582              
583 9     9   75 use strict;
  9         17  
  9         297  
584 9     9   45 use warnings;
  9         17  
  9         324  
585              
586 9     9   53 use Bio::Util::DNA qw(reverse_complement);
  9         21  
  9         3851  
587              
588             sub new {
589 24     24   42 my $class = shift;
590 24         72 my $self = [ {}, {} ];
591 24         272 bless $self, $class;
592             }
593              
594 2     2   61 sub forward { return $_[0][0] }
595 0     0   0 sub reverse { return $_[0][1] }
596              
597             sub store {
598 1850     1850   3079 my ( $self, $residue, $codon, $reverse ) = @_;
599              
600 1850   33     5251 $reverse ||= ${ reverse_complement($codon) };
  0         0  
601              
602 1850         4491 $self->[0]->{$codon} = $residue;
603 1850         5348 $self->[1]->{$reverse} = $residue;
604             }
605              
606             sub push {
607 1850     1850   3013 my ( $self, $residue, $codon, $reverse ) = @_;
608              
609 1850   33     3177 $reverse ||= ${ reverse_complement($codon) };
  0         0  
610              
611 1850   100     4708 $self->[0]->{$residue} ||= [];
612 1850   100     4074 $self->[1]->{$residue} ||= [];
613              
614 1850         1913 push @{ $self->[0]->{$residue} }, $codon;
  1850         4895  
615 1850         2050 push @{ $self->[1]->{$residue} }, $reverse;
  1850         3936  
616              
617 1850         3094 foreach my $i ( 0 .. 1 ) {
618 3700         4316 my %seen = map { $_ => undef } @{ $self->[$i]->{$residue} };
  29770         48381  
  3700         7383  
619 3700         15759 $self->[$i]->{$residue} = [ sort { $a cmp $b } keys %seen ];
  70744         100642  
620             }
621             }
622             }
623              
624             1;
625              
626             =head1 MISC
627              
628             These are the original translation tables. The translation tables used by this
629             module have been boostrapped and compacted. They were first expanded to include
630             translations for degenerate nucleotides and allow ambiguous amino acids to be
631             the targets of translation (e.g. every effort has been made to give a
632             translation that isn't "X"). Then, the tables had reduntant columns removed;
633             any codon implied by the presence of degenerate-nucleotide-containing codon was
634             removed.
635              
636             {
637             name "Standard" ,
638             name "SGC0" ,
639             id 1 ,
640             ncbieaa "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
641             sncbieaa "---M---------------M---------------M----------------------------"
642             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
643             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
644             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
645             },
646             {
647             name "Vertebrate Mitochondrial" ,
648             name "SGC1" ,
649             id 2 ,
650             ncbieaa "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSS**VVVVAAAADDEEGGGG",
651             sncbieaa "--------------------------------MMMM---------------M------------"
652             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
653             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
654             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
655             },
656             {
657             name "Yeast Mitochondrial" ,
658             name "SGC2" ,
659             id 3 ,
660             ncbieaa "FFLLSSSSYY**CCWWTTTTPPPPHHQQRRRRIIMMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
661             sncbieaa "----------------------------------MM----------------------------"
662             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
663             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
664             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
665             },
666             {
667             name "Mold Mitochondrial; Protozoan Mitochondrial;"
668             name "Coelenterate Mitochondrial; Mycoplasma; Spiroplasma" ,
669             name "SGC3" ,
670             id 4 ,
671             ncbieaa "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
672             sncbieaa "--MM---------------M------------MMMM---------------M------------"
673             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
674             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
675             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
676             },
677             {
678             name "Invertebrate Mitochondrial" ,
679             name "SGC4" ,
680             id 5 ,
681             ncbieaa "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSSSSVVVVAAAADDEEGGGG",
682             sncbieaa "---M----------------------------MMMM---------------M------------"
683             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
684             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
685             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
686             },
687             {
688             name "Ciliate Nuclear; Dasycladacean Nuclear; Hexamita Nuclear" ,
689             name "SGC5" ,
690             id 6 ,
691             ncbieaa "FFLLSSSSYYQQCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
692             sncbieaa "-----------------------------------M----------------------------"
693             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
694             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
695             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
696             },
697             {
698             name "Echinoderm Mitochondrial; Flatworm Mitochondrial" ,
699             name "SGC8" ,
700             id 9 ,
701             ncbieaa "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG",
702             sncbieaa "-----------------------------------M---------------M------------"
703             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
704             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
705             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
706             },
707             {
708             name "Euplotid Nuclear" ,
709             name "SGC9" ,
710             id 10 ,
711             ncbieaa "FFLLSSSSYY**CCCWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
712             sncbieaa "-----------------------------------M----------------------------"
713             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
714             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
715             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
716             },
717             {
718             name "Bacterial and Plant Plastid" ,
719             id 11 ,
720             ncbieaa "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
721             sncbieaa "---M---------------M------------MMMM---------------M------------"
722             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
723             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
724             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
725             },
726             {
727             name "Alternative Yeast Nuclear" ,
728             id 12 ,
729             ncbieaa "FFLLSSSSYY**CC*WLLLSPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
730             sncbieaa "-------------------M---------------M----------------------------"
731             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
732             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
733             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
734             },
735             {
736             name "Ascidian Mitochondrial" ,
737             id 13 ,
738             ncbieaa "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSSGGVVVVAAAADDEEGGGG",
739             sncbieaa "---M------------------------------MM---------------M------------"
740             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
741             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
742             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
743             },
744             {
745             name "Alternative Flatworm Mitochondrial" ,
746             id 14 ,
747             ncbieaa "FFLLSSSSYYY*CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG",
748             sncbieaa "-----------------------------------M----------------------------"
749             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
750             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
751             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
752             } ,
753             {
754             name "Blepharisma Macronuclear" ,
755             id 15 ,
756             ncbieaa "FFLLSSSSYY*QCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
757             sncbieaa "-----------------------------------M----------------------------"
758             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
759             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
760             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
761             } ,
762             {
763             name "Chlorophycean Mitochondrial" ,
764             id 16 ,
765             ncbieaa "FFLLSSSSYY*LCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
766             sncbieaa "-----------------------------------M----------------------------"
767             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
768             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
769             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
770             } ,
771             {
772             name "Trematode Mitochondrial" ,
773             id 21 ,
774             ncbieaa "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNNKSSSSVVVVAAAADDEEGGGG",
775             sncbieaa "-----------------------------------M---------------M------------"
776             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
777             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
778             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
779             } ,
780             {
781             name "Scenedesmus obliquus Mitochondrial" ,
782             id 22 ,
783             ncbieaa "FFLLSS*SYY*LCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
784             sncbieaa "-----------------------------------M----------------------------"
785             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
786             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
787             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
788             } ,
789             {
790             name "Thraustochytrium Mitochondrial" ,
791             id 23 ,
792             ncbieaa "FF*LSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG",
793             sncbieaa "--------------------------------M--M---------------M------------"
794             -- Base1 TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG
795             -- Base2 TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG
796             -- Base3 TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG
797             }
798              
799             =head1 AUTHOR
800              
801             Kevin Galinsky,
802              
803             =cut
804              
805             # keep translation tables in the __DATA__ section
806             __DATA__