t/AlignIO/AlignIO.t: fix number of tests in plan (fixup c523e6bed866)
[bioperl-live.git] / Bio / SeqFeature / SubSeq.pm
blob296a4061dc58cd8ff1740efdf18a647fb2ec4ec8
2 # BioPerl module for Bio::SeqFeature::SubSeq
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Copyright Florent Angly
8 # You may distribute this module under the same terms as perl itself
11 =head1 NAME
13 Bio::SeqFeature::SubSeq - Feature representing a subsequence
15 =head1 SYNOPSIS
17 # SubSeq with implicit sequence
18 use Bio::Seq;
19 my $template = Bio::Seq->new( -seq => 'AAAAACCCCCGGGGGTTTTT' );
20 $subseq = Bio::SeqFeature::Amplicon->new(
21 -start => 6,
22 -end => 15,
23 -template => $template,
25 print "Subsequence is: ".$amplicon->seq->seq."\n"; # Should be 'CCCCCGGGGG'
27 # SubSeq with explicit sequence
28 use Bio::SeqFeature::Subseq;
29 my $subseq = Bio::SeqFeature::Amplicon->new(
30 -seq => $seq_object,
33 =head1 DESCRIPTION
35 Bio::SeqFeature::SubSeq extends L<Bio::SeqFeature::Generic> features to
36 represent a subsequence. When this feature is attached to a template sequence,
37 the sequence of feature is the subsequence of the template at this location. The
38 purpose of this class is to represent a sequence as a feature without having to
39 explicitly store its sequence string.
41 Of course, you might have reasons to explicitly set a sequence. In that case,
42 note that the length of the sequence is allowed to not match the position of the
43 feature. For example, you can set sequence of length 10 in a SubSeq feature that
44 spans positions 30 to 50 of the template if you so desire.
46 =head1 FEEDBACK
48 =head2 Mailing Lists
50 User feedback is an integral part of the evolution of this and other
51 Bioperl modules. Send your comments and suggestions preferably to one
52 of the Bioperl mailing lists. Your participation is much appreciated.
54 bioperl-l@bioperl.org - General discussion
55 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
57 =head2 Support
59 Please direct usage questions or support issues to the mailing list:
61 I<bioperl-l@bioperl.org>
63 rather than to the module maintainer directly. Many experienced and
64 reponsive experts will be able look at the problem and quickly
65 address it. Please include a thorough description of the problem
66 with code and data examples if at all possible.
68 =head2 Reporting Bugs
70 Report bugs to the Bioperl bug tracking system to help us keep track
71 the bugs and their resolution. Bug reports can be submitted via
72 the web:
74 https://github.com/bioperl/bioperl-live/issues
76 =head1 AUTHOR
78 Florent Angly <florent.angly@gmail.com>
80 =head1 APPENDIX
82 The rest of the documentation details each of the object
83 methods. Internal methods are usually preceded with a _
85 =cut
88 package Bio::SeqFeature::SubSeq;
90 use strict;
92 use base qw(Bio::SeqFeature::Generic);
94 =head2 new
96 Title : new()
97 Usage : my $subseq = Bio::SeqFeature::SubSeq( -start => 1, -end => 10, -strand => -1);
98 Function: Instantiate a new Bio::SeqFeature::SubSeq feature object
99 Args : -seq , the sequence object or sequence string of the feature (optional)
100 -template , attach the feature to the provided parent template sequence or feature (optional).
101 Note that you must specify the feature location to do this.
102 -start, -end, -location, -strand and all other L<Bio::SeqFeature::Generic> argument can be used.
103 Returns : A Bio::SeqFeature::SubSeq object
105 =cut
107 sub new {
108 my ($class, @args) = @_;
109 my $self = $class->SUPER::new(@args);
110 my ($seq, $template) = $self->_rearrange([qw(SEQ TEMPLATE)], @args);
111 if (defined $seq) {
112 # Set the subsequence explicitly
113 if (not ref $seq) {
114 # Convert string to sequence object
115 $seq = Bio::PrimarySeq->new( -seq => $seq );
116 } else {
117 # Sanity check
118 if (not $seq->isa('Bio::PrimarySeqI')) {
119 $self->throw("Expected a sequence object but got a '".ref($seq)."'\n");
122 $self->seq($seq);
124 if ($template) {
125 if ( not($self->start) || not($self->end) ) {
126 $self->throw('Could not attach feature to template $template because'.
127 ' the feature location was not specified.');
130 # Need to attach to parent sequence and then add sequence feature
131 my $template_seq;
132 if ($template->isa('Bio::SeqFeature::Generic')) {
133 $template_seq = $template->entire_seq;
134 } elsif ($template->isa('Bio::SeqI')) {
135 $template_seq = $template;
136 } else {
137 $self->throw("Expected a Bio::SeqFeature::Generic or Bio::SeqI object".
138 " as template, but got '$template'.");
140 $self->attach_seq($template_seq);
141 $template->add_SeqFeature($self);
144 return $self;
148 =head2 seq
150 Title : seq()
151 Usage : my $seq = $subseq->seq();
152 Function: Get or set the sequence object of this SubSeq feature. If no sequence
153 was provided, but the subseq is attached to a sequence, get the
154 corresponding subsequence.
155 Returns : A sequence object or undef
156 Args : None.
158 =cut
160 sub seq {
161 my ($self, $value) = @_;
162 if (defined $value) {
163 # The sequence is explicit
164 if ( not(ref $value) || not $value->isa('Bio::PrimarySeqI') ) {
165 $self->throw("Expected a sequence object but got a '".ref($value)."'\n");
167 $self->{seq} = $value;
169 my $seq = $self->{seq};
170 if (not defined $seq) {
171 # The sequence is implied
172 $seq = $self->SUPER::seq;
174 return $seq;
178 =head2 length
180 Title : seq()
181 Usage : my $length = $subseq->seq();
182 Function: Get the length of the SubSeq feature. It is similar to the length()
183 method of L<Bio::Generic::SeqFeature>, which computes length based
184 on the location of the feature. However, if the feature was not
185 given a location, return the length of the subsequence if possible.
186 Returns : integer or undef
187 Args : None.
189 =cut
191 sub length {
192 my ($self) = @_;
193 # Try length from location first
194 if ($self->start && $self->end) {
195 return $self->SUPER::length();
197 # Then try length from subsequence
198 my $seq = $self->seq;
199 if (defined $seq) {
200 return length $seq->seq;
202 # We failed
203 return undef;