Bio::Tools::CodonTable::is_start_codon: check in case of ambiguous codons (#266)
[bioperl-live.git] / lib / Bio / SeqIO / FTHelper.pm
blob1a40d77830cfbe61e9fda5088a7ad4fe6eaae61a
2 # BioPerl module for Bio::SeqIO::FTHelper
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Ewan Birney <birney@ebi.ac.uk>
8 # Copyright Ewan Birney
10 # You may distribute this module under the same terms as perl itself
12 # POD documentation - main docs before the code
14 =head1 NAME
16 Bio::SeqIO::FTHelper - Helper class for EMBL/Genbank feature tables
18 =head1 SYNOPSIS
20 Used by Bio::SeqIO::EMBL,Bio::SeqIO::genbank, and Bio::SeqIO::swiss to
21 help process the Feature Table
23 =head1 DESCRIPTION
25 Represents one particular Feature with the following fields
27 key - the key of the feature
28 loc - the location string of the feature
29 <other fields> - other fields
31 =head1 FEEDBACK
33 =head2 Mailing Lists
35 User feedback is an integral part of the evolution of this and other
36 Bioperl modules. Send your comments and suggestions preferably to one
37 of the Bioperl mailing lists. Your participation is much appreciated.
39 bioperl-l@bioperl.org - General discussion
40 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
42 =head2 Support
44 Please direct usage questions or support issues to the mailing list:
46 I<bioperl-l@bioperl.org>
48 rather than to the module maintainer directly. Many experienced and
49 reponsive experts will be able look at the problem and quickly
50 address it. Please include a thorough description of the problem
51 with code and data examples if at all possible.
53 =head2 Reporting Bugs
55 Report bugs to the Bioperl bug tracking system to help us keep track
56 the bugs and their resolution. Bug reports can be submitted via the web:
58 https://github.com/bioperl/bioperl-live/issues
60 =head1 AUTHOR - Ewan Birney
62 Email birney@ebi.ac.uk
64 =head1 CONTRIBUTORS
66 Jason Stajich jason@bioperl.org
68 =head1 APPENDIX
70 The rest of the documentation details each of the object
71 methods. Internal methods are usually preceded with a _
73 =cut
76 # Let the code begin...
79 package Bio::SeqIO::FTHelper;
81 use strict;
83 use Bio::SeqFeature::Generic;
84 use Bio::Location::Simple;
85 use Bio::Location::Fuzzy;
86 use Bio::Location::Split;
88 use base qw(Bio::Root::Root);
90 sub new {
91 my ($class, @args) = @_;
93 # no chained new because we make lots and lots of these.
94 my $self = {};
95 bless $self,$class;
96 $self->{'_field'} = {};
97 return $self;
100 =head2 _generic_seqfeature
102 Title : _generic_seqfeature
103 Usage : $fthelper->_generic_seqfeature($annseq, "GenBank")
104 Function: processes fthelper into a generic seqfeature
105 Returns : TRUE on success and otherwise FALSE
106 Args : The Bio::Factory::LocationFactoryI object to use for parsing
107 location strings. The ID (e.g., display_id) of the sequence on which
108 this feature is located, optionally a string indicating the source
109 (GenBank/EMBL/SwissProt)
111 =cut
113 sub _generic_seqfeature {
114 my ($fth, $locfac, $seqid, $source) = @_;
115 my ($sf);
117 # set a default if not specified
118 if(! defined($source)) {
119 $source = "EMBL/GenBank/SwissProt";
122 # initialize feature object
123 $sf = Bio::SeqFeature::Generic->direct_new();
125 # parse location; this may cause an exception, in which case we gently
126 # recover and ignore this feature
129 my $loc;
130 eval {
131 $loc = $locfac->from_string($fth->loc);
134 if(! $loc) {
135 $fth->warn("exception while parsing location line [" . $fth->loc .
136 "] in reading $source, ignoring feature " .
137 $fth->key() . " (seqid=" . $seqid . "): " . $@);
138 return;
141 # set additional location attributes
142 if($seqid && (! $loc->is_remote())) {
143 $loc->seq_id($seqid); # propagates if it is a split location
147 # set attributes of feature
148 $sf->location($loc);
149 $sf->primary_tag($fth->key);
150 $sf->source_tag($source);
151 $sf->seq_id($seqid);
152 foreach my $key ( keys %{$fth->field} ){
153 foreach my $value ( @{$fth->field->{$key}} ) {
154 $sf->add_tag_value($key,$value);
157 return $sf;
161 =head2 from_SeqFeature
163 Title : from_SeqFeature
164 Usage : @fthelperlist = Bio::SeqIO::FTHelper::from_SeqFeature($sf,
165 $context_annseq);
166 Function: constructor of fthelpers from SeqFeatures
168 : The additional annseq argument is to allow the building of FTHelper
169 : lines relevant to particular sequences (ie, when features are spread over
170 : enteries, knowing how to build this)
171 Returns : an array of FThelpers
172 Args : seq features
175 =cut
177 sub from_SeqFeature {
178 my ($sf, $context_annseq) = @_;
179 my @ret;
182 # If this object knows how to make FThelpers, then let it
183 # - this allows us to store *really* weird objects that can write
184 # themselves to the EMBL/GenBank...
187 if ( $sf->can("to_FTHelper") ) {
188 return $sf->to_FTHelper($context_annseq);
191 my $fth = Bio::SeqIO::FTHelper->new();
192 my $key = $sf->primary_tag();
193 my $locstr = $sf->location->to_FTstring;
195 # ES 25/06/01 Commented out this code, Jason to double check
196 #The location FT string for all simple subseqfeatures is already
197 #in the Split location FT string
199 # going into sub features
200 #foreach my $sub ( $sf->sub_SeqFeature() ) {
201 #my @subfth = &Bio::SeqIO::FTHelper::from_SeqFeature($sub);
202 #push(@ret, @subfth);
205 $fth->loc($locstr);
206 $fth->key($key);
207 $fth->field->{'note'} = [];
209 # the lines below take specific tags (e.g. /score=23 ) and re-enter them as
210 # new tags like /note="score=25" - if the file is round-tripped this creates
211 # duplicate values
213 #$sf->source_tag && do { push(@{$fth->field->{'note'}},"source=" . $sf->source_tag ); };
215 #($sf->can('score') && $sf->score) && do { push(@{$fth->field->{'note'}},
216 # "score=" . $sf->score ); };
218 #($sf->can('frame') && $sf->frame) && do { push(@{$fth->field->{'note'}},
219 # "frame=" . $sf->frame ); };
221 #$sf->strand && do { push(@{$fth->field->{'note'}},"strand=" . $sf->strand ); };
223 foreach my $tag ( $sf->get_all_tags ) {
224 # Tags which begin with underscores are considered
225 # private, and are therefore not printed
226 next if $tag =~ /^_/;
227 if ( !defined $fth->field->{$tag} ) {
228 $fth->field->{$tag} = [];
230 foreach my $val ( $sf->get_tag_values($tag) ) {
231 push(@{$fth->field->{$tag}},$val);
234 push(@ret, $fth);
236 unless (@ret) {
237 $context_annseq->throw("Problem in processing seqfeature $sf - no fthelpers. Error!");
239 foreach my $ft (@ret) {
240 if ( !$ft->isa('Bio::SeqIO::FTHelper') ) {
241 $sf->throw("Problem in processing seqfeature $sf - made a $fth!");
245 return @ret;
249 =head2 key
251 Title : key
252 Usage : $obj->key($newval)
253 Function:
254 Example :
255 Returns : value of key
256 Args : newvalue (optional)
259 =cut
261 sub key {
262 my ($obj, $value) = @_;
263 if ( defined $value ) {
264 $obj->{'key'} = $value;
266 return $obj->{'key'};
270 =head2 loc
272 Title : loc
273 Usage : $obj->loc($newval)
274 Function:
275 Example :
276 Returns : value of loc
277 Args : newvalue (optional)
280 =cut
282 sub loc {
283 my ($obj, $value) = @_;
284 if ( defined $value ) {
285 $obj->{'loc'} = $value;
287 return $obj->{'loc'};
291 =head2 field
293 Title : field
294 Usage :
295 Function:
296 Example :
297 Returns :
298 Args :
301 =cut
303 sub field {
304 my ($self) = @_;
306 return $self->{'_field'};
309 =head2 add_field
311 Title : add_field
312 Usage :
313 Function:
314 Example :
315 Returns :
316 Args :
319 =cut
321 sub add_field {
322 my ($self, $key, $val) = @_;
324 if ( !exists $self->field->{$key} ) {
325 $self->field->{$key} = [];
327 push( @{$self->field->{$key}} , $val);