File Coverage

blib/lib/Bio/Das/Feature.pm
Criterion Covered Total %
statement 148 292 50.6
branch 42 148 28.3
condition 7 53 13.2
subroutine 37 69 53.6
pod 44 61 72.1
total 278 623 44.6


line stmt bran cond sub pod time code
1             package Bio::Das::Feature;
2              
3 1     1   4 use strict;
  1         2  
  1         32  
4 1     1   6 use vars qw($VERSION @ISA);
  1         2  
  1         50  
5 1         6 use overload '""' => 'toString',
6 1     1   5 cmp => '_cmp';
  1         2  
7              
8 1     1   72 use Bio::Root::Root;
  1         2  
  1         27  
9 1     1   5 use Bio::Das::Util; # for rearrange
  1         2  
  1         45  
10 1     1   1086 use Bio::LocationI;
  1         5642  
  1         32  
11              
12             # we follow the SeqFeatureI interface but don't actually need
13             # to load it.
14 1     1   965 use Bio::SeqFeatureI;
  1         53488  
  1         4056  
15              
16             @ISA = qw(Bio::Root::Root Bio::SeqFeatureI Bio::PrimarySeqI Bio::LocationI);
17              
18             $VERSION = '0.91';
19              
20             # aliases for Ace::Sequence::Feature compatibility
21             *subtype = \&method;
22             *segments = *sub_seqFeature = \&get_SeqFeatures;
23             *display_id= *info = \&label;
24             *seq_id = \&refseq;
25             *make_link = \&link;
26             *desc = \&description;
27              
28             sub new {
29 267     267 1 324 my $class = shift;
30 267         1310 my ($segment,$id,$start,$stop) = rearrange([qw(segment id start stop)],@_);
31 267         2373 return bless { segment => $segment,
32             id => $id,
33             start => $start,
34             stop => $stop,
35             },$class;
36             }
37              
38             sub clone {
39 0     0 1 0 my $self = shift;
40 0         0 my %new = %$self;
41 0         0 my $clone = bless \%new,ref $self;
42 0 0       0 if (ref(my $t = $clone->type)) {
43 0 0       0 my $type = $t->can('clone') ? $t->clone : bless {%$t},ref $t;
44 0         0 $clone->type($type);
45             }
46              
47 0 0       0 if (ref(my $g = $clone->group)) {
48 0 0       0 my $group = $g->can('clone') ? $g->clone : bless {%$g},ref $g;
49 0         0 $clone->group($group);
50             }
51 0         0 $clone;
52             }
53              
54             sub segment {
55 64     64 0 63 my $self = shift;
56 64         99 my $d = $self->{segment};
57 64 50       112 $self->{segment} = shift if @_;
58 64         165 $d;
59             }
60              
61             sub start {
62 686     686 1 765 my $self = shift;
63 686         932 my $d = $self->{start};
64 686 100       1257 $self->{start} = shift if @_;
65 686         2350 $d;
66             }
67              
68             sub stop {
69 960     960 1 1026 my $self = shift;
70 960         1179 my $d = $self->{stop};
71 960 100       1756 $self->{stop} = shift if @_;
72 960         2938 $d;
73             }
74              
75 0     0 1 0 sub length {my $self = shift; $self->stop-$self->start+1}
  0         0  
76              
77 1     1 1 675 sub refseq { shift->segment->refseq }
78              
79             sub display_name {
80 0     0 1 0 my $self = shift;
81 0   0     0 return $self->label || $self->group_label || $self->id;
82             }
83              
84             sub id {
85 9390     9390 1 10333 my $self = shift;
86 9390         12682 my $d = $self->{id};
87 9390 50       17254 $self->{id} = shift if @_;
88 9390         47839 $d;
89             }
90              
91             sub label {
92 9045     9045 1 10098 my $self = shift;
93 9045         12081 my $d = $self->{label};
94 9045 100       16740 $self->{label} = shift if @_;
95 9045         35054 $d;
96             }
97              
98             sub notes {
99 0     0 0 0 my $self = shift;
100 0 0       0 return unless exists $self->{note};
101 0         0 @{$self->{note}};
  0         0  
102             }
103              
104             sub attributes {
105 0     0 1 0 my $self = shift;
106 0 0       0 if (@_) {
107 0         0 return $self->each_tag_value(@_);
108             } else {
109 0 0       0 return $self->{attributes} ? %{$self->{attributes}} : ();
  0         0  
110             }
111             }
112              
113             sub has_tag {
114 0     0 1 0 my $self = shift;
115 0         0 my $tag = shift;
116 0         0 return exists $self->{attributes}{$tag};
117             }
118              
119             sub all_tags {
120 0     0 1 0 my $self = shift;
121 0         0 return keys %{$self->{attributes}};
  0         0  
122             }
123              
124             sub add_tag_value {
125 0     0 1 0 my $self = shift;
126 0         0 my ($tag_name,@tag_values) = @_;
127 0         0 push @{$self->{attributes}{$tag_name}},@tag_values;
  0         0  
128             }
129              
130             sub remove_tag {
131 0     0 1 0 my $self = shift;
132 0         0 my $tag_name = shift;
133 0         0 delete $self->{attributes}{$tag_name};
134             }
135              
136             sub each_tag_value {
137 0     0 1 0 my $self = shift;
138 0         0 my $tag = shift;
139 0 0       0 my $value = $self->{attributes}{$tag} or return;
140 0 0       0 return CORE::ref $value ? @{$self->{attributes}{$tag}}
  0         0  
141             : $self->{attributes}{$tag};
142             }
143              
144             sub note {
145 0     0 1 0 my $self = shift;
146 0         0 my $d = $self->{note};
147 0 0       0 $self->{note} = shift if @_;
148 0         0 $d;
149             }
150              
151             sub add_note {
152 0     0 0 0 my $self = shift;
153 0         0 my ($tag,$value) = @_;
154 0 0       0 if (defined $tag) {
155 0         0 push @{$self->{attributes}{$tag}},$value;
  0         0  
156             } else {
157 0         0 push @{$self->{note}},$value;
  0         0  
158             }
159             }
160              
161             sub target {
162 170     170 1 200 my $self = shift;
163 170         283 my $d = $self->{target};
164 170 50       326 if (@_) {
165 170         297 my ($id,$start,$stop) = @_;
166 170         607 $self->{target} = [ $id,$start,$stop ];
167             }
168 170 50       1238 return unless $d;
169 0 0       0 return wantarray ? @$d # (id,start,stop,label) in list context
170             : ref($self)->new($self->segment,@$d);# a Feature object in scalar context
171             }
172              
173             sub target_id {
174 0     0 0 0 my $self = shift;
175 0 0 0     0 return $self->{'target'}[0] if exists $self->{'target'} && ref $self->{'target'} eq 'ARRAY';
176             }
177              
178             sub target_start {
179 0     0 0 0 my $self = shift;
180 0 0 0     0 return $self->{'target'}[1] if exists $self->{'target'} && ref $self->{'target'} eq 'ARRAY';
181             }
182              
183             sub target_stop {
184 0     0 0 0 my $self = shift;
185 0 0 0     0 return $self->{'target'}[2] if exists $self->{'target'} && ref $self->{'target'} eq 'ARRAY';
186             }
187              
188             sub type {
189 966     966 1 1027 my $self = shift;
190 966         1410 my $d = $self->{type};
191 966 100       1918 $self->{type} = shift if @_;
192 966         3599 $d;
193             }
194              
195             sub method {
196 213     213 1 662 my $self = shift;
197 213 50       334 my $type = $self->type or return;
198 213         589 $type->method(@_);
199             }
200              
201             sub category {
202 75     75 1 109 my $self = shift;
203 75 100       128 my $type = $self->type or return;
204 12   50     25 return eval {$type->category}||'';
205             }
206              
207             sub reference {
208 0     0 0 0 my $self = shift;
209 0 0       0 my $type = $self->type or return;
210 0         0 $type->reference;
211             }
212              
213             sub score {
214 204     204 1 249 my $self = shift;
215 204         263 my $d = $self->{score};
216 204 50       650 $self->{score} = shift if @_;
217 204         1164 $d;
218             }
219              
220             sub orientation {
221 330     330 1 367 my $self = shift;
222 330         475 my $d = $self->{orientation};
223 330 100       1036 $self->{orientation} = shift if @_;
224 330         1239 $d;
225             }
226              
227             sub phase {
228 204     204 1 289 my $self = shift;
229 204         300 my $d = $self->{phase};
230 204 50       809 $self->{phase} = shift if @_;
231 204         1018 $d;
232             }
233              
234             sub parent_id {
235 675     675 0 690 my $self = shift;
236 675         914 my $d = $self->{parent};
237 675 100       1304 $self->{parent} = shift if @_;
238 675         1305 $d;
239             }
240              
241             sub child_ids {
242 204     204 0 208 my $self = shift;
243 204   50     1164 my $d = ($self->{children} ||= []);
244 204 50       382 $self->{children} = shift if @_;
245 204         630 return @$d;
246             }
247              
248             sub add_child_id {
249 204     204 0 200 my $self = shift;
250 204         189 my $child = shift;
251              
252 204   100     476 $self->{children} ||= [];
253 204         192 push @{$self->{children}},$child;
  204         659  
254             }
255              
256             sub group {
257 408     408 1 430 my $self = shift;
258 408         679 my $d = $self->{group};
259 408 100       827 $self->{group} = shift if @_;
260 408         1749 $d;
261             }
262              
263             sub group_type {
264 267     267 0 291 my $self = shift;
265 267         344 my $d = $self->{group_type};
266 267 100       633 $self->{group_type} = shift if @_;
267 267         582 $d;
268             }
269              
270             sub group_label {
271 204     204 0 226 my $self = shift;
272 204         284 my $d = $self->{group_label};
273 204 50       548 $self->{group_label} = shift if @_;
274 204         354 $d;
275             }
276              
277             sub link {
278 332     332 1 365 my $self = shift;
279 332         520 my $d = $self->{link};
280 332 100       785 $self->{link} = shift if @_;
281 332         1417 $d;
282             }
283              
284             sub link_label {
285 204     204 1 408 my $self = shift;
286 204         304 my $d = $self->{link_label};
287 204 50       557 $self->{link_label} = shift if @_;
288 204         1065 $d;
289             }
290              
291             sub target_label {
292 170     170 1 220 my $self = shift;
293 170         235 my $d = $self->{target_label};
294 170 50       491 $self->{target_label} = shift if @_;
295 170         871 $d;
296             }
297              
298             sub description {
299 0     0 1 0 my $self = shift;
300 0 0 0     0 $self->note || $self->link_label || $self->target_label;
301             }
302              
303 1     1 1 7 sub end { shift->stop(@_) }
304              
305             sub toString {
306 8919     8919 0 10343 my $self = shift;
307 8919   33     15733 return $self->label || $self->id || ref($self);
308             }
309              
310             # for aceperl compatibility
311             sub strand {
312 5     5 1 12 my $s = shift->{orientation};
313 5 50       11 return 0 if $s eq '.';
314 5 50       11 return '+1' if $s eq '+';
315 5 50       18 return '-1' if $s eq '-';
316 0         0 $s;
317             }
318              
319             sub reversed {
320 0     0 0 0 return shift->strand eq '-';
321             }
322              
323             sub seq {
324 0     0 1 0 my $self = shift;
325 0 0       0 my $seg = $self->segment or return;
326 0 0       0 my $das = $seg->das or return;
327 0         0 my $newseg = $das->segment($self->seq_id,$self->start,$self->end);
328 0         0 my $dna = $newseg->dna;
329 0 0       0 if ($self->strand < 0) {
330 0         0 $dna =~ tr/gatcGATC/ctagCTAG/;
331 0         0 $dna = reverse $dna;
332             }
333 0         0 $dna;
334             }
335              
336             sub get_SeqFeatures {
337 6     6 1 555 my $self = shift;
338 6         9 my $type = shift;
339 6 50       17 my $subfeat = $self->{subfeatures} or return;
340 6         14 $self->sort_features;
341 6         9 my @a;
342 6 50       11 if ($type) {
343 0 0       0 my $features = $subfeat->{lc $type} or return;
344 0         0 @a = @{$features};
  0         0  
345             } else {
346 6         9 @a = map {@{$_}} values %{$subfeat};
  6         8  
  6         18  
  6         13  
347             }
348 6         32 return @a;
349             }
350              
351             sub add_subfeature {
352 204     204 1 227 my $self = shift;
353 204         195 my $feature = shift;
354 204         355 my $type = $feature->method;
355 204   100     821 my $subfeat = $self->{subfeatures}{lc $type} ||= [];
356 204         226 push @{$subfeat},$feature;
  204         775  
357             }
358              
359             # adjust a feature so that its boundaries are synched with its subparts' boundaries.
360             # this works recursively, so subfeatures can contain other features
361             sub adjust_bounds {
362 0     0 1 0 my $self = shift;
363 0         0 my $t = $self->{target};
364              
365 0 0       0 if (my $subfeat = $self->{subfeatures}) {
366 0         0 for my $list (values %$subfeat) {
367 0         0 for my $feat (@$list) {
368              
369             # fix up our bounds to hold largest subfeature
370 0         0 my($start,$stop,$strand) = $feat->adjust_bounds;
371 0 0       0 $self->{fstrand} = $strand unless defined $self->{fstrand};
372 0 0       0 if ($start <= $stop) {
373 0 0 0     0 $self->{start} = $start if !defined($self->{start}) || $start < $self->{start};
374 0 0 0     0 $self->{stop} = $stop if !defined($self->{stop}) || $stop > $self->{stop};
375             } else {
376 0 0 0     0 $self->{start} = $start if !defined($self->{start}) || $start > $self->{start};
377 0 0 0     0 $self->{stop} = $stop if !defined($self->{stop}) || $stop < $self->{stop};
378             }
379              
380             # fix up endpoints of targets too
381 0         0 my $st = $feat->{target};
382 0 0 0     0 next unless $t && $st;
383 0         0 ($start,$stop) = (@{$st}[1,2]);
  0         0  
384 0 0       0 if ($start < $stop) {
385 0 0 0     0 $t->[1] = $start if !defined($t->[1]) || $start < $t->[1]; # start
386 0 0 0     0 $t->[2] = $stop if !defined($t->[2]) || $stop > $t->[2]; # stop
387             } else {
388 0 0 0     0 $t->[1] = $start if !defined($t->[1]) || $start > $t->[1]; # start
389 0 0 0     0 $t->[2] = $stop if !defined($t->[2]) || $stop < $t->[2];
390             }
391             }
392             }
393             }
394              
395 0         0 ($self->{start},$self->{stop},$self->strand);
396             }
397              
398             # sort features
399             sub sort_features {
400 6     6 1 9 my $self = shift;
401 6 100       20 return if $self->{sorted}++;
402 5 50       12 my $strand = $self->strand or return;
403 5 50       15 my $subfeat = $self->{subfeatures} or return;
404 5         13 for my $type (keys %$subfeat) {
405 0         0 $subfeat->{$type} = [map { $_->[0] }
  0         0  
406 0         0 sort {$a->[1] <=> $b->[1] }
407 0         0 map { [$_,$_->start] }
408 5 50       14 @{$subfeat->{$type}}] if $strand > 0;
409 6         37 $subfeat->{$type} = [map { $_->[0] }
  1         6  
410 6         15 sort {$b->[1] <=> $a->[1]}
411 5         12 map { [$_,$_->start] }
412 5 50       12 @{$subfeat->{$type}}] if $strand < 0;
413             }
414             }
415              
416             sub compound {
417 0     0 1 0 my $self = shift;
418 0         0 my $d = $self->{compound};
419 0 0       0 $self->{compound} = shift if @_;
420 0         0 $d;
421             }
422              
423 0     0 1 0 sub primary_tag { shift->type }
424 0     0 0 0 sub class { shift->method }
425 0     0 1 0 sub source_tag { shift->method }
426             sub source {
427 2     2 1 456 my $type = shift->type;
428 2         7 my ($method,$source) = split ':',$type;
429 2         12 return $source;
430             }
431             sub gff_string {
432 0     0 1   my $self = shift;
433 0           return join "\t",(
434             $self->refseq,
435             $self->method,
436             $self->type,
437             $self->start,
438             $self->end,
439             $self->score,
440             $self->{orientation},
441             $self->phase,
442             "group " . $self->group ." ; link " . $self->link
443             );
444             }
445              
446             sub _cmp {
447 0     0     my $self = shift;
448 0           my ($b,$reversed) = @_;
449 0           my $a = $self->toString;
450 0 0         ($a,$b) = ($b,$a) if $reversed;
451 0           $a cmp $b;
452             }
453              
454             sub is_remote {
455 0     0 1   1;
456             }
457              
458             sub location {
459 0     0 1   my $self = shift;
460 0 0         require Bio::Location::Split unless Bio::Location::Split->can('new');
461 0           my $location;
462 0 0         if (my @segments = $self->segments) {
463 0           $location = Bio::Location::Split->new();
464 0           foreach (@segments) {
465 0           $location->add_sub_Location($_);
466             }
467             } else {
468 0           $location = $self;
469             }
470 0           $location;
471             }
472              
473             sub each_Location {
474 0     0 1   my $self = shift;
475 0 0         require Bio::Location::Simple unless Bio::Location::Simple->can('new');
476 0 0         if (my @segments = $self->segments) {
477 0           return map {
478 0           Bio::Location::Simple->new(-start => $_->start,
479             -end => $_->end,
480             -strand => $_->strand);
481             } @segments;
482             } else {
483 0           return Bio::Location::Simple->new(-start => $self->start,
484             -end => $self->end,
485             -strand => $self->strand);
486             }
487             }
488              
489             sub location_string {
490 0     0 0   my $self = shift;
491 0 0         my @segments = $self->segments or return $self->to_FTstring;
492 0           join ',',map {$_->to_FTstring} @segments;
  0            
493             }
494              
495             sub coordinate_policy {
496 0 0   0 1   require Bio::Location::WidestCoordPolicy unless Bio::Location::WidestCoordPolicy->can('new');
497 0           return Bio::Location::WidestCoordPolicy->new();
498             }
499              
500             sub name {
501 0     0 0   my $self = shift;
502 0           my $d = $self->{name};
503 0 0         $self->{name} = shift if @_;
504 0           $d;
505             }
506              
507             1;
508              
509             __END__
510              
511             =head1 NAME
512              
513             Bio::Das::Segment::Feature - A genomic annotation
514              
515             =head1 SYNOPSIS
516              
517             use Bio::Das;
518              
519             # contact a DAS server using the "elegans" data source
520             my $das = Bio::Das->new('http://www.wormbase.org/db/das' => 'elegans');
521              
522             # fetch a segment
523             my $segment = $das->segment(-ref=>'CHROMOSOME_I',-start=>10_000,-stop=>20_000);
524              
525             # get features from segment
526             for my $feature ($segment->features) {
527             my $id = $feature->id;
528             my $label = $feature->label;
529             my $type = $feature->type;
530             my $category = $feature->category;
531             my $refseq = $feature->refseq;
532             my $reference = $feature->reference;
533             my $start = $feature->start;
534             my $stop = $feature->stop;
535             my $score = $feature->score;
536             my $orientation = $feature->orientation;
537             my $phase = $feature->phase;
538             my $link = $feature->link;
539             my $group = $feature->group;
540             my @subs = $feature->sub_seqFeature;
541             }
542              
543             =head1 DESCRIPTION
544              
545             A Bio::Das::Segment::Feature object contains information about a
546             feature on the genome retrieve from a DAS server. Each feature --
547             also known as an "annotation" -- has a start and end position on the
548             genome relative to a reference sequence, as well as a human-readable
549             label, a feature type, a category, and other information. Some
550             features may have subfeatures. The attributes of a feature are
551             described at http://biodas.org.
552              
553             =head2 OBJECT CREATION
554              
555             Bio::Das::Segment::Feature objects are created by calling the
556             features() method of a Bio::Das::Segment object created earlier. See
557             L<Bio::Das::Segment> for details.
558              
559             =head2 OBJECT METHODS
560              
561             The following methods provide access to the attributes of a feature.
562             Most are implemented as read/write accessors: calling them without an
563             argument returns the current value of the attribute. Calling the
564             methods with an argument sets the attribute and returns its previous
565             value.
566              
567             =over 4
568              
569             =item $id = $feature->id([$newid])
570              
571             Get or set the feature ID. This is an identifier for the feature,
572             unique across the DAS server from which it was retrieved.
573              
574             =item $label = $feature->label([$newlabel])
575              
576             Get or set the label for the feature. This is an optional
577             human-readable label that may be used to display the feature in text
578             form. You may use the ID if label() returns undef.
579              
580             =item $type = $feature->type([$newtype])
581              
582             Get or set the type of the feature. This is a required attribute. The
583             value returned is an object of type Bio::Das::Type, which contains
584             information about the type of the annotation and the method used to
585             derive it.
586              
587             =item $segment = $feature->([$newsegment])
588              
589             Get or set the Bio::Das::Segment from which this feature was derived.
590              
591             =item $source = $feature->source
592              
593             Get the Bio::Das object from which this feature was retrieved. This
594             method is a front end to the associated segment's source() method, and
595             is therefore read-only.
596              
597             =item $refseq = $feature->refseq
598              
599             Get the reference sequence on which this feature's coordinates are
600             based. This method is a front end to the associated segment's
601             refseq() method, and is therefore read-only.
602              
603             =item $start = $feature->start([$newstart])
604              
605             Get or set the starting position of the feature, in refseq
606             coordinates.
607              
608             =item $stop = $feature->stop([$newstop])
609              
610             Get or set the stopping position of the feature, in refseq
611             coordinates.
612              
613             =item $isreference = $feature->stop([$newreference])
614              
615             Get or set the value of the "reference" flag, which is true if the
616             feature can be used as a sequence coordinate landmark.
617              
618             =item $method = $feature->method
619              
620             Return the ID of the method used to derive this feature. This is a
621             front end to the feature type's method() method (redundancy intended)
622             and is therefore read-only.
623              
624             =item $category = $feature->category
625              
626             Return the ID of the category in which this feature calls. This is a
627             front end to the feature type's category() method and is therefore
628             read-only.
629              
630             =item $score = $feature->score([$newscore])
631              
632             Get or set the score of this feature, a floating point number which
633             might mean something in the right context.
634              
635             =item $orientation = $feature->orientation([$neworientation])
636              
637             Get or set the orientation of this feature relative to the genomic
638             reference sequence. This is one of the values +1, 0 or -1.
639              
640             =item $phase = $feature->phase([$newphase])
641              
642             Get or set the phase of the feature (its position relative to a
643             reading frame). The returned value can be 0, 1, 2 or undef if the
644             phase is irrelevant to this feature type.
645              
646             =item $group = $feature->group([$newgroup])
647              
648             Get or set the group ID for the feature. Groups are used to group
649             together logically-related features, such as the exons of a gene
650             model.
651              
652             =item $url = $feature->link([$newurl])
653              
654             Get or set the URL that will return additional information about the
655             feature.
656              
657             =item $label = $feature->link_label([$newlabel])
658              
659             Get or set the label that the DAS server recommends should be used for
660             the link.
661              
662             =item $note = $feature->note([$newnote])
663              
664             Get or set the human-readable note associated with the feature.
665              
666             =item $feature->each_tag_value()
667             =item $feature->all_tags()
668             =item $feature->add_tag_value()
669             =item $feature->remove_tag()
670             =item $feature->attributes()
671              
672             The tag* methods work just like they do in Bio::SeqFeatureI. The
673             attributes() method follows the conventions in Bio::DB::SeqFeature.
674              
675             =item $target = $feature->target
676              
677             =item ($target,$start,$stop) = $feature->target
678              
679             =item $feature->target($target,$start,$stop)
680              
681             These three methods get or set the target that is optionally
682             associated with alignments. In a scalar context, target() returns the
683             ID of the target, while in an array context, the method returns a
684             three-element list consisting of the target ID, and the start and end
685             position of the alignment.
686              
687             You may pass a three-element list to change the target and range.
688              
689             =item $target_label = $feature->target_label([$newlabel])
690              
691             This method returns an optional label assigned to the target.
692              
693             =item $description = $feature->description
694              
695             This method returns a human-readable description of the feature. It
696             returns the value of note(), link_label() or target_label(), in that
697             priority.
698              
699             =item @segments = $feature->segments
700              
701             =item @segments = $feature->sub_seqFeature
702              
703             These methods are aliases. Both return an array of sub-parts of the
704             feature in the form of Das::Sequence::Feature objects. Currently
705             (March 2001) this is only implemented for grouped objects of type
706             "similarity" and for transcripts (the union of introns and exons in a
707             group).
708              
709             =head2 Bio::SeqFeatureI METHODS
710              
711             In addition to the methods listed above, Bio::Das::Segment::Feature
712             implements all the methods required for the Bio::SeqFeatureI class.
713              
714             =head2 get_SeqFeatures
715              
716             Title : get_SeqFeatures
717             Usage : @feat = $feature->get_SeqFeatures([$method])
718             Function: get subfeatures
719             Returns : a list of Bio::DB::GFF::Feature objects
720             Args : a feature method (optional)
721             Status : Public
722              
723             This method returns a list of any subfeatures that belong to the main
724             feature. For those features that contain heterogeneous subfeatures,
725             you can retrieve a subset of the subfeatures by providing a method
726             name to filter on.
727              
728             =cut
729              
730             =head2 add_subfeature
731              
732             Title : add_subfeature
733             Usage : $feature->add_subfeature($feature)
734             Function: add a subfeature to the feature
735             Returns : nothing
736             Args : a Bio::DB::GFF::Feature object
737             Status : Public
738              
739             This method adds a new subfeature to the object. It is used
740             internally by aggregators, but is available for public use as well.
741              
742             =cut
743              
744             =head2 adjust_bounds
745              
746             Title : adjust_bounds
747             Usage : $feature->adjust_bounds
748             Function: adjust the bounds of a feature
749             Returns : ($start,$stop,$strand)
750             Args : none
751             Status : Public
752              
753             This method adjusts the boundaries of the feature to enclose all its
754             subfeatures. It returns the new start, stop and strand of the
755             enclosing feature.
756              
757             =cut
758              
759             =head2 sort_features
760              
761             Title : sort_features
762             Usage : $feature->sort_features
763             Function: sort features
764             Returns : nothing
765             Args : none
766             Status : Public
767              
768             This method sorts subfeatures in ascending order by their start
769             position. For reverse strand features, it sorts subfeatures in
770             descending order. After this is called sub_SeqFeature will return the
771             features in order.
772              
773             This method is called internally by merged_segments().
774              
775             =cut
776              
777             =head2 compound
778              
779             Title : compound
780             Usage : $flag = $f->compound([$newflag])
781             Function: get or set the compound flag
782             Returns : a boolean
783             Args : a new flag (optional)
784             Status : Public
785              
786             This method gets or sets a flag indicated that the feature is not a
787             primary one from the DAS server, but the result of aggregation.
788              
789             =cut
790              
791              
792              
793             =head2 STRING OVERLOADING
794              
795             When used in a string context, Bio::Das::Segment::Feature objects
796             invoke the toString() method. This returns the value of the feature's
797             label, or invokes the inherited Bio::Das::Segment->toString() method
798             if no label is available.
799              
800             =head1 AUTHOR
801              
802             Lincoln Stein <lstein@cshl.org>.
803              
804             Copyright (c) 2001 Cold Spring Harbor Laboratory
805              
806             This library is free software; you can redistribute it and/or modify
807             it under the same terms as Perl itself. See DISCLAIMER.txt for
808             disclaimers of warranty.
809              
810             =head1 SEE ALSO
811              
812             L<Bio::Das>, L<Bio::Das::Type>, L<Bio::Das::Segment>,
813             L<Bio::Das::Transcript>, L<Bio::Das::Segment::GappedAlignment>,
814             L<Bio::RangeI>
815              
816             =cut