tag fourth (and hopefully last) alpha
[bioperl-live.git] / branch-1-6 / Bio / AlignIO / Handler / GenericAlignHandler.pm
blob337df850ec6e5422694b03166710c799bcc2011f
1 # Let the code begin...
3 package Bio::AlignIO::Handler::GenericAlignHandler;
5 use strict;
6 use warnings;
8 use Bio::Annotation::Collection;
9 use Bio::Annotation::Comment;
10 use Bio::Annotation::SimpleValue;
11 use Bio::Annotation::Target;
12 use Bio::Annotation::DBLink;
13 use Bio::Annotation::Reference;
14 use Bio::SimpleAlign;
15 use Data::Dumper;
17 use base qw(Bio::Root::Root Bio::HandlerBaseI);
19 # only stockholm is defined for now...
20 my %HANDLERS = (
21 # stockholm has sequence and alignment specific annotation; this
22 'stockholm' => {
23 'CONSENSUS_META' => \&_generic_consensus_meta,
24 'SEQUENCE' => \&_generic_metaseq,
25 'NAMED_META' => \&_generic_metaseq,
26 'ACCESSION' => \&_generic_store,
27 'ALPHABET' => \&_generic_store,
28 'ID' => \&_generic_store,
29 'DESCRIPTION' => \&_generic_store,
30 'REFERENCE' => \&_generic_reference,
31 'DBLINK' => \&_stockholm_target,
32 'DATABASE_COMMENT' => \&_generic_comment,
33 'ALIGNMENT_COMMENT' => \&_generic_comment,
34 '_DEFAULT_' => \&_generic_simplevalue
38 sub new {
39 my ($class, @args) = @_;
40 my $self = $class->SUPER::new(@args);
41 my ($format, $verbose) = $self->_rearrange([qw(FORMAT VERBOSE)], @args);
42 $self->throw("Must define alignment record format") if !$format;
43 $verbose && $self->verbose($verbose);
44 $self->format($format);
45 $self->handler_methods();
46 # if we intend at a later point we can add a Builder
47 #$builder && $self->alignbuilder($builder);
48 return $self;
51 sub handler_methods {
52 my $self = shift;
53 if (!($self->{'handlers'})) {
54 $self->throw("No handlers defined for alignment format ",$self->format)
55 unless exists $HANDLERS{$self->format};
56 $self->{'handlers'} = $HANDLERS{$self->format};
58 return ($self->{'handlers'});
61 sub data_handler {
62 my ($self, $data) = @_;
63 my $nm = $data->{NAME} || $self->throw("No name tag defined!");
64 # this should handle data on the fly w/o caching; any caching should be
65 # done in the driver!
66 my $method = (exists $self->{'handlers'}->{$nm}) ? ($self->{'handlers'}->{$nm}) :
67 (exists $self->{'handlers'}->{'_DEFAULT_'}) ? ($self->{'handlers'}->{'_DEFAULT_'}) :
68 undef;
69 if (!$method) {
70 $self->debug("No handler defined for $nm\n");
71 return;
73 $self->$method($data);
76 sub reset_parameters {
77 my $self = shift;
78 $self->{'_params'} = undef;
79 $self->{'_nse_cache'} = undef;
80 $self->{'_features'} = undef;
83 sub format {
84 my $self = shift;
85 if (@_) {
86 my $format = lc shift;
87 $self->throw("Format $format not supported") unless exists $HANDLERS{$format};
88 $self->{'_alignformat'} = $format;
90 return $self->{'_alignformat'};
93 sub get_params {
94 my ($self, @ids) = @_;
95 my $data;
96 if (scalar(@ids)) {
97 for my $id (@ids) {
98 if (!index($id, '-')==0) {
99 $id = '-'.$id ;
101 $data->{$id} = $self->{'_params'}->{$id} if (exists $self->{'_params'}->{$id});
103 $data ||= {};
104 } else {
105 $data = $self->{'_params'};
107 return $data;
110 sub set_params {
111 shift->throw('Not implemented yet!');
114 sub build_alignment {
115 my $self = shift;
116 my %init;
117 $self->process_seqs;
118 my $param = $self->get_params;
119 if (defined $param->{-seqs}) {
120 return Bio::SimpleAlign->new(%$param, -source => $self->format);
124 sub annotation_collection {
125 my ($self, $coll) = @_;
126 if ($coll) {
127 $self->throw("Must have Bio::AnnotationCollectionI ".
128 "when explicitly setting annotation_collection()")
129 unless (ref($coll) && $coll->isa('Bio::AnnotationCollectionI'));
130 $self->{'_params'}->{'-annotation'} = $coll;
131 } elsif (!exists($self->{'_params'}->{'-annotation'})) {
132 $self->{'_params'}->{'-annotation'} = Bio::Annotation::Collection->new()
134 return $self->{'_params'}->{'-annotation'};
137 sub seq_annotation_collection {
138 my ($self, $coll) = @_;
139 if ($coll) {
140 $self->throw("Must have Bio::AnnotationCollectionI ".
141 "when explicitly setting seq_annotation_collection()")
142 unless (ref($coll) && $coll->isa('Bio::AnnotationCollectionI'));
143 $self->{'_params'}->{'-seq_annotation'} = $coll;
144 } elsif (!exists($self->{'_params'}->{'-seq_annotation'})) {
145 $self->{'_params'}->{'-seq_annotation'} = Bio::Annotation::Collection->new()
147 return $self->{'_params'}->{'-seq_annotation'};
150 sub process_seqs {
151 my $self = shift;
153 my $data = $self->get_params(qw(-seqs -seq_class -consensus_meta));
154 my $class = $data->{-seq_class} || 'Bio::LocatableSeq';
155 # cache classes loaded already
156 if (!exists($self->{'_loaded_modules'}->{$class})) {
157 $self->_load_module($class);
158 $self->{'_loaded_modules'}->{$class}++;
160 # process any meta sequence data
161 if ( $data->{-consensus_meta} && !UNIVERSAL::isa($data->{-consensus_meta},'Bio::Seq::Meta')) {
162 my $ref = $data->{-consensus_meta};
163 if (!exists($self->{'_loaded_modules'}->{'Bio::Seq::Meta'})) {
164 $self->_load_module('Bio::Seq::Meta');
165 $self->{'_loaded_modules'}->{'Bio::Seq::Meta'}++;
167 my $ms = Bio::Seq::Meta->new();
168 for my $tag (sort keys %{$ref}) {
169 $ms->named_meta($tag, $ref->{$tag});
171 $self->{'_params'}->{'-consensus_meta'} = $ms;
173 # this should always be an array ref!
174 for my $seq (@{$data->{-seqs}}) {
175 next if (UNIVERSAL::isa($seq,'Bio::LocatableI'));
176 # process anything else
177 $self->_from_nse($seq) if $seq->{NSE};
178 if (UNIVERSAL::isa($seq,'HASH')) {
179 my %param;
180 for my $p (keys %$seq) {
181 $param{'-'.lc $p} = $seq->{$p} if exists $seq->{$p};
183 my $ls = $class->new(%param);
184 # a little switcheroo to attach the sequence
185 # (though using it to get seq() doesn't work correctly yet!)
186 if (defined $seq->{NSE} &&
187 exists $self->{'_features'} &&
188 exists $self->{'_features'}->{ $seq->{NSE} }) {
189 for my $feat (@{ $self->{'_features'}->{ $seq->{NSE} } }) {
190 push @{ $self->{'_params'}->{'-features'} }, $feat;
191 $feat->attach_seq($ls);
194 $seq = $ls;
199 ####################### SEQUENCE HANDLERS #######################
201 # any sequence data for a Bio::Seq::Meta
202 sub _generic_metaseq {
203 my ($self, $data) = @_;
204 return unless $data;
205 $self->throw("No alignment position passed") if !exists($data->{BLOCK_LINE});
206 $self->throw("Alignment position must be an index greater than 0") if $data->{BLOCK_LINE} < 1;
207 $self->{'_params'}->{'-seq_class'} = 'Bio::Seq::Meta';
208 my $index = $data->{BLOCK_LINE} - 1;
209 if (my $nse = $self->{'_params'}->{'-seqs'}->[$index]->{NSE}) {
210 $self->throw("NSE in passed data doesn't match stored data in same position: $nse") unless $nse eq $data->{NSE};
211 } else {
212 $self->{'_params'}->{'-seqs'}->[$index]->{NSE} = $data->{NSE};
214 if ($data->{NAME} eq 'SEQUENCE') {
215 $self->{'_params'}->{'-seqs'}->[$index]->{SEQ} .= $data->{DATA};
216 } elsif ($data->{NAME} eq 'NAMED_META') {
217 $self->{'_params'}->{'-seqs'}->[$index]->{NAMED_META}->{$data->{META_TAG}} .= $data->{DATA};
221 sub _generic_consensus_meta {
222 my ($self, $data) = @_;
223 return unless $data;
224 if ($data->{NAME} eq 'CONSENSUS_META') {
225 $self->{'_params'}->{'-consensus_meta'}->{$data->{META_TAG}} .= $data->{DATA};
229 # any sequence data for a Bio::LocatableSeq
230 sub _generic_locatableseq {
231 my ($self, $data) = @_;
232 return unless $data;
233 $self->throw("No alignment position passed") if !exists($data->{BLOCK_LINE});
234 $self->throw("Alignment position must be an index greater than 0") if $data->{BLOCK_LINE} < 1;
235 my $index = $data->{BLOCK_LINE} - 1;
236 if (my $nse = $self->{'_params'}->{'-seqs'}->[$index]->{NSE}) {
237 $self->throw("NSE in passed data doesn't match stored data in same position: $nse") if $nse ne $data->{NSE};
238 } else {
239 $self->{'_params'}->{'-seqs'}->[$index]->{NSE} = $data->{NSE};
241 if ($data->{NAME} eq 'SEQUENCE') {
242 $self->{'_params'}->{'-seqs'}->[$index]->{SEQ} .= $data->{DATA};
246 ####################### RAW DATA HANDLERS #######################
248 # store by data name (ACCESSION, ID, etc), which can be mapped to the
249 # appropriate alignment or sequence parameter
250 sub _generic_store {
251 my ($self, $data) = @_;
252 return unless $data;
253 if ($data->{ALIGNMENT}) {
254 $self->{'_params'}->{'-'.lc $data->{NAME}} = $data->{DATA};
255 } else {
256 $self->{'_params'}->{'-seq_'.lc $data->{NAME}}->{$data->{NSE}} = $data->{DATA}
260 sub _generic_reference {
261 my ($self, $data) = @_;
262 my $ref = Bio::Annotation::Reference->new(-title => $data->{TITLE},
263 -authors => $data->{AUTHORS},
264 -pubmed => $data->{PUBMED},
265 -location => $data->{JOURNAL},
266 -tagname => lc $data->{NAME});
267 $self->annotation_collection->add_Annotation($ref);
270 sub _generic_simplevalue {
271 my ($self, $data) = @_;
272 my $sv = Bio::Annotation::SimpleValue->new(-value => $data->{DATA},
273 -tagname => lc $data->{NAME});
274 $self->annotation_collection->add_Annotation($sv);
277 sub _generic_comment {
278 my ($self, $data) = @_;
279 my $comment = Bio::Annotation::Comment->new(-type => lc $data->{NAME},
280 -text => $data->{DATA},
281 -tagname => lc $data->{NAME});
282 $self->annotation_collection->add_Annotation($comment);
285 # Some DBLinks in Stockholm format are unique, so a unique handler for them
286 sub _stockholm_target {
287 my ($self, $data) = @_;
288 # process database info
289 $self->_from_stk_dblink($data);
290 my $comment;
291 # Bio::Annotation::Target is now a DBLink, but has additional (RangeI)
292 # capabilities (for PDB data)
293 my $dblink = Bio::Annotation::Target->new(
294 -database => $data->{DBLINK_DB},
295 -primary_id => $data->{DBLINK_ACC},
296 -optional_id => $data->{DBLINK_OPT},
297 -start => $data->{DBLINK_START},
298 -end => $data->{DBLINK_END},
299 -strand => $data->{DBLINK_STRAND},
300 -comment => $comment,
301 -tagname => 'dblink',
303 if ($data->{ALIGNMENT}) {
304 # Alignment-specific DBLinks
305 $self->annotation_collection->add_Annotation($dblink);
306 } else {
307 # Sequence-specific DBLinks
308 # These should come with identifying information of some sort
309 # (ID/START/END/STRAND). Make into a SeqFeature (SimpleAlign is
310 # FeatureHolderI) spanning the length acc. to the NSE. Add the DBLink as
311 # Annotation specific to that SeqFeature, store in an internal hash by
312 # NSE so we can tie the LocatableSeq to the proper Features
313 $self->_from_nse($data) if $data->{NSE};
314 $self->throw("Must supply an sequence DISPLAY_ID or NSE for sequence-related
315 DBLinks") unless $data->{ACCESSION_NUMBER} || $data->{DISPLAY_ID};
316 my $sf = Bio::SeqFeature::Generic->new(-seq_id => $data->{DISPLAY_ID},
317 -accession_number => $data->{ACCESSION_NUMBER},
318 -start => $data->{START},
319 -end => $data->{END},
320 -strand => $data->{STRAND}
322 $sf->annotation->add_Annotation($dblink);
323 # index by NSE
324 push @{ $self->{'_features'}->{ $data->{NSE} } }, $sf;
325 #$self->seq_annotation_collection->add_Annotation($dblink);
329 ####################### HELPER METHODS #######################
331 # returns ACCESSION VERSION START END STRAND ALPHABET
332 # cached for multiple lookups, should reset in between uses
333 sub _from_nse {
334 my ($self, $data) = @_;
335 return unless my $nse = $data->{NSE};
336 $data->{ALPHABET} = $self->get_params('-alphabet')->{'-alphabet'} || 'protein';
337 # grab any accessions if present, switch out with ACCESSION from NSE
338 # (move that to primary_id)
339 my $new_acc;
340 if (exists $self->{'_params'}->{'-seq_accession'}) {
341 $new_acc = $self->{'_params'}->{'-seq_accession'}->{$data->{NSE}};
343 if ($nse =~ m{(\S+?)(?:\.(\d+))?/(\d+)-(\d+)}xmso) {
344 my $strand = $data->{ALPHABET} eq 'dna' || $data->{ALPHABET} eq 'rna' ? 1 : undef;
345 my ($start, $end) = ($3, $4);
346 if ($start > $end) {
347 ($start, $end, $strand) = ($end, $start, -1);
349 $data->{ACCESSION_NUMBER} = $new_acc || $1;
350 $data->{DISPLAY_ID} = $1;
351 $data->{VERSION} = $2;
352 $data->{START} = $start;
353 $data->{END} = $end;
354 $data->{STRAND} = $strand;
355 } else {
356 # we can parse for version here if needed
357 $data->{DISPLAY_ID} = $data->{NSE};
361 # this will probably be split up into subhandlers based on Record/DB
362 sub _from_stk_dblink {
363 my ($self, $data) = @_;
364 return unless my $raw = $data->{DATA};
365 my @rawdata = split(m{\s*;\s*}, $raw);
366 my %dblink_data;
367 if ($rawdata[0] eq 'PDB') {
368 # fix for older Stockholm PDB range format
369 if (scalar(@rawdata) == 3 && $rawdata[2] =~ m{-}) {
370 @rawdata[2,3] = split('-',$rawdata[2],2);
372 $self->throw("Not standard PDB form: ".$data->{DATA}) if scalar(@rawdata) != 4;
373 my ($main, $chain) = split(m{\s+}, $rawdata[1]);
374 %dblink_data = (
375 DBLINK_DB => $rawdata[0],
376 DBLINK_ACC => $main,
377 DBLINK_OPT => $chain || '',
378 DBLINK_START => $rawdata[2],
379 DBLINK_END => $rawdata[3]
381 } elsif ($rawdata[0] eq 'SCOP') {
382 $self->throw("Not standard SCOP form: ".$data->{DATA}) if scalar(@rawdata) != 3;
383 %dblink_data = (
384 DBLINK_DB => $rawdata[0],
385 DBLINK_ACC => $rawdata[1],
386 DBLINK_OPT => $rawdata[2],
388 } else {
389 $self->warn("Some data missed: ".$data->{DATA}) if scalar(@rawdata) > 2;
390 %dblink_data = (
391 DBLINK_DB => $rawdata[0],
392 DBLINK_ACC => $rawdata[1],
395 while (my ($k, $v) = each %dblink_data) {
396 $data->{$k} = $v if $v;
402 __END__
404 # $Id: GenericAlignHandler.pm 14816 2008-08-21 16:00:12Z cjfields $
406 # BioPerl module for Bio::AlignIO::Handler::GenericAlignHandler
408 # Please direct questions and support issues to <bioperl-l@bioperl.org>
410 # Cared for by Chris Fields
412 # Copyright Chris Fields
414 # You may distribute this module under the same terms as perl itself
416 # POD documentation - main docs before the code
418 # Documentation after the __END__ marker
420 =head1 NAME
422 Bio::AlignIO::Handler::GenericAlignHandler - Bio::HandlerI-based
423 generic data handler class for alignment-based data
425 =head1 SYNOPSIS
427 # MyHandler is a GenericAlignHandler object.
428 # inside a parser (driver) constructor....
430 $self->alignhandler($handler || MyHandler->new(-format => 'stockholm'));
432 # in next_aln() in driver...
434 $hobj = $self->alignhandler();
436 # roll data up into hashref chunks, pass off into Handler for processing...
438 $hobj->data_handler($data);
440 # or retrieve Handler methods and pass data directly to Handler methods...
442 my $hmeth = $hobj->handler_methods;
444 if ($hmeth->{ $data->{NAME} }) {
445 my $mth = $hmeth->{ $data->{NAME} };
446 $hobj->$mth($data);
449 =head1 DESCRIPTION
451 This is an experimental implementation of a alignment-based HandlerBaseI parser
452 and may change over time. It is possible that the way handler methods are set up
453 will change over development to allow more flexibility.
455 Standard Developer caveats:
457 Here thar be dragoons...
459 Consider yourself warned!
461 =head2 NOTES
463 As in the SeqIO Handler object (still in development), data is passed in as
464 chunks. The Annotation and SeqFeatures are essentially the same as the SeqIO
465 parser; the significant difference is that data hash being passed could pertain
466 to either the alignment or to a specific sequence, so an extra tag may be needed
467 to disambiguate between the two in some cases. Here I use the ALIGNMENT tag as a
468 boolean flag: it must be present and set to 0 for the data to be tagged for
469 Bio::LocatableSeq or similar (in all other cases it is assumed to be for the
470 alignment). In some cases this will not matter (the actual sequence data, for
471 instance) but it is highly recommmended adding this tag in to prevent possible
472 ambiguities.
474 This is the current Annotation data chunk (via Data::Dumper):
476 $VAR1 = {
477 'NAME' => 'REFERENCE',
478 'DATA' => '1 (bases 1 to 10001)'
479 'AUTHORS' => 'International Human Genome Sequencing Consortium.'
480 'TITLE' => 'The DNA sequence of Homo sapiens'
481 'JOURNAL' => 'Unpublished (2003)'
482 'ALIGNMENT' => 1,
485 In the case of LocatableSeqs, one can pass them in as follows for simplicity
486 (note the block line):
488 $VAR1 = {
489 'NAME' => 'SEQUENCE',
490 'BLOCK_LINE' => 0,
491 'NSE' => 'Q7WNI7_BORBR/113-292',
492 'ALPHABET' => 'protein',
493 'DATA' => 'VALILGVYRRL...CYVNREM..RAG....QW',
494 'ALIGNMENT' => 0
497 This can be done as the parser parses each block instead of parsing all the
498 blocks and then passing them in one at a time; the handler will store the
499 sequence data by the block line in an internal hash, concatenating them along
500 the way. This behaviour is b/c the alignment building step requires that
501 the sequence be checked for start/end/strand, possible meta sequence, optional
502 accession, etc.
504 Similarly, a Meta sequence line can be passed in as follows:
506 $VAR1 = {
507 'NAME' => 'NAMED_META',
508 'BLOCK_LINE' => 0,
509 'NSE' => 'Q7WNI7_BORBR/113-292',
510 'META_KEY' => 'pAS',
511 'DATA' => '................................',
512 'ALIGNMENT' => 0
515 The meta sequence will be checked against the NSE for the block position and
516 stored based on the meta tag. A meta sequence does not have to correspond to a
517 real sequence. At this time, unique meta sequence tags must be used for each
518 sequence or they will be overwritten (this may change).
520 An alignment consensus string:
522 $VAR1 = {
523 'NAME' => 'CONSENSUS',
524 'DATA' => 'VALILGVYRRL...CYVNREM..RAG....QW',
525 'ALIGNMENT' => 1
528 A consensus meta sequence:
530 $VAR1 = {
531 'NAME' => 'CONSENSUS_META',
532 'META_KEY' => 'pAS',
533 'DATA' => '................................',
534 'ALIGNMENT' => 1
537 =head1 FEEDBACK
539 =head2 Mailing Lists
541 User feedback is an integral part of the evolution of this and other
542 Bioperl modules. Send your comments and suggestions preferably to one
543 of the Bioperl mailing lists. Your participation is much appreciated.
545 bioperl-l@bioperl.org - General discussion
546 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
548 =head2 Support
550 Please direct usage questions or support issues to the mailing list:
552 I<bioperl-l@bioperl.org>
554 rather than to the module maintainer directly. Many experienced and
555 reponsive experts will be able look at the problem and quickly
556 address it. Please include a thorough description of the problem
557 with code and data examples if at all possible.
559 =head2 Reporting Bugs
561 Report bugs to the Bioperl bug tracking system to help us keep track
562 the bugs and their resolution. Bug reports can be submitted via the
563 web:
565 http://bugzilla.open-bio.org/
567 =head1 AUTHOR - Chris Fields
569 Email cjfields at bioperl dot org
571 =head1 APPENDIX
573 The rest of the documentation details each of the object methods. Internal
574 methods are usually preceded with a _
576 =cut
578 =head2 new
580 Title : new
581 Usage :
582 Function:
583 Returns :
584 Args : -format Sequence format to be mapped for handler methods
585 -builder Bio::Seq::SeqBuilder object (normally defined in
586 SequenceStreamI object implementation constructor)
587 Throws : On undefined '-format' sequence format parameter
588 Note : Still under heavy development
590 =cut
592 =head1 L<Bio::HandlerBaseI> implementing methods
594 =head2 handler_methods
596 Title : handler_methods
597 Usage : $handler->handler_methods('GenBank')
598 %handlers = $handler->handler_methods();
599 Function: Retrieve the handler methods used for the current format() in
600 the handler. This assumes the handler methods are already
601 described in the HandlerI-implementing class.
602 Returns : a hash reference with the data type handled and the code ref
603 associated with it.
604 Args : [optional] String representing the sequence format. If set here
605 this will also set sequence_format()
606 Throws : On unimplemented sequence format in %HANDLERS
608 =cut
610 =head2 data_handler
612 Title : data_handler
613 Usage : $handler->data_handler($data)
614 Function: Centralized method which accepts all data chunks, then distributes
615 to the appropriate methods for processing based on the chunk name
616 from within the HandlerBaseI object.
618 One can also use
619 Returns : None
620 Args : an hash ref containing a data chunk.
622 =cut
624 =head2 reset_parameters
626 Title : reset_parameters
627 Usage : $handler->reset_parameters()
628 Function: Resets the internal cache of data (normally object parameters for
629 a builder or factory)
630 Returns : None
631 Args : None
633 =cut
635 =head2 format
637 Title : format
638 Usage : $handler->format('GenBank')
639 Function: Get/Set the format for the report/record being parsed. This can be
640 used to set handlers in classes which are capable of processing
641 similar data chunks from multiple driver modules.
642 Returns : String with the sequence format
643 Args : [optional] String with the sequence format
644 Note : The format may be used to set the handlers (as in the
645 current GenericRichSeqHandler implementation)
647 =cut
649 =head2 get_params
651 Title : get_params
652 Usage : $handler->get_params('-species')
653 Function: Convenience method used to retrieve the specified
654 parameters from the internal parameter cache
655 Returns : Hash ref containing parameters requested and data as
656 key-value pairs. Note that some parameter values may be
657 objects, arrays, etc.
658 Args : List (array) representing the parameters requested
660 =cut
662 =head2 set_params
664 Title : set_params
665 Usage : $handler->set_param({'-seqs' => $seqs})
666 Function: Convenience method used to set specific parameters
667 Returns : None
668 Args : Hash ref containing the data to be passed as key-value pairs
670 =cut
672 =head1 Methods unique to this implementation
674 =head2 build_alignment
676 Title : build_alignment
677 Usage :
678 Function:
679 Returns : a Bio::SimpleAlign
680 Args :
681 Throws :
682 Note : This may be replaced by a Builder object at some point
684 =cut
686 =head2 annotation_collection
688 Title : annotation_collection
689 Usage :
690 Function:
691 Returns :
692 Args :
693 Throws :
694 Note :
696 =cut
698 =head2 seq_annotation_collection
700 Title : seq_annotation_collection
701 Usage :
702 Function:
703 Returns :
704 Args :
705 Throws :
706 Note :
708 =cut
710 =head2 process_seqs
712 Title : process_seqs
713 Usage : $handler->process_seqs;
714 Function: checks internal sequences to ensure they are converted over
715 to the proper Bio::AlignI-compatible sequence class
716 Returns : 1 if successful
717 Args : none
719 =cut