sync w/ main trunk
[bioperl-live.git] / Bio / Seq / QualI.pm
blobb08dc58aabb6ff2cdf88280de6d9799d1f0d9775
1 # $Id$
3 # BioPerl module for Bio::Seq::QualI
5 # Please direct questions and support issues to <bioperl-l@bioperl.org>
7 # Cared for by Chad Matsalla <bioinformatics@dieselwurks.com
9 # Copyright Chad Matsalla
11 # You may distribute this module under the same terms as perl itself
13 # POD documentation - main docs before the code
15 =head1 NAME
17 Bio::Seq::QualI - Interface definition for a Bio::Seq::Qual
19 =head1 SYNOPSIS
21 # get a Bio::Seq::Qual compliant object somehow
23 # to test this is a seq object
25 $obj->isa("Bio::Seq::QualI")
26 || $obj->throw("$obj does not implement the Bio::Seq::QualI interface");
28 # accessors
30 $string = $obj->qual();
31 $substring = $obj->subqual(12,50);
32 $display = $obj->display_id(); # for human display
33 $id = $obj->primary_id(); # unique id for this object,
34 # implementation defined
35 $unique_key= $obj->accession_number();
36 # unique biological id
40 =head1 DESCRIPTION
42 This object defines an abstract interface to basic quality
43 information. PrimaryQual is an object just for the quality and its
44 name(s), nothing more. There is a pure perl implementation of this in
45 Bio::Seq::PrimaryQual. If you just want to use Bio::Seq::PrimaryQual
46 objects, then please read that module first. This module defines the
47 interface, and is of more interest to people who want to wrap their
48 own Perl Objects/RDBs/FileSystems etc in way that they "are" bioperl
49 quality objects, even though it is not using Perl to store the
50 sequence etc.
52 This interface defines what bioperl consideres necessary to "be" a
53 sequence of qualities, without providing an implementation of
54 this. (An implementation is provided in Bio::Seq::PrimaryQual). If you
55 want to provide a Bio::Seq::PrimaryQual 'compliant' object which in
56 fact wraps another object/database/out-of-perl experience, then this
57 is the correct thing to wrap, generally by providing a wrapper class
58 which would inherit from your object and this Bio::Seq::QualI
59 interface. The wrapper class then would have methods lists in the
60 "Implementation Specific Functions" which would provide these methods
61 for your object.
64 =head1 FEEDBACK
66 =head2 Mailing Lists
68 User feedback is an integral part of the evolution of this and other
69 Bioperl modules. Send your comments and suggestions preferably to one
70 of the Bioperl mailing lists. Your participation is much appreciated.
72 bioperl-l@bioperl.org - General discussion
73 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
75 =head2 Support
77 Please direct usage questions or support issues to the mailing list:
79 L<bioperl-l@bioperl.org>
81 rather than to the module maintainer directly. Many experienced and
82 reponsive experts will be able look at the problem and quickly
83 address it. Please include a thorough description of the problem
84 with code and data examples if at all possible.
86 =head2 Reporting Bugs
88 Report bugs to the Bioperl bug tracking system to help us keep track
89 the bugs and their resolution. Bug reports can be submitted via the
90 web:
92 http://bugzilla.open-bio.org/
94 =head1 AUTHOR - Chad Matsalla
96 This module is heavily based on Bio::Seq::PrimarySeq and is modeled after
97 or outright copies sections of it. Thanks Ewan!
99 Email bioinformatics@dieselwurks.com
101 =head1 APPENDIX
103 The rest of the documentation details each of the object methods.
104 Internal methods are usually preceded with a _
106 =cut
109 # Let the code begin...
112 package Bio::Seq::QualI;
113 use strict;
114 use Carp;
116 use base qw(Bio::Root::RootI);
118 =head1 Implementation Specific Functions
120 These functions are the ones that a specific implementation must
121 define.
123 =head2 qual()
125 Title : qual()
126 Usage : @quality_values = @{$obj->qual()};
127 Function: Returns the quality as a reference to an array containing the
128 quality values. The individual elements of the quality array are
129 not validated and can be any numeric value.
130 Returns : A reference to an array.
131 Status :
133 =cut
135 sub qual {
136 my ($self) = @_;
137 if( $self->can('throw') ) {
138 $self->throw("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
139 } else {
140 confess("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
144 =head2 subqual($start,$end)
146 Title : subqual($start,$end)
147 Usage : @subset_of_quality_values = @{$obj->subseq(10,40)};
148 Function: returns the quality values from $start to $end, where the
149 first value is 1 and the number is inclusive, ie 1-2 are the first
150 two bases of the sequence. Start cannot be larger than end but can
151 be equal.
152 Returns : A reference to an array.
153 Args : a start position and an end position
156 =cut
158 sub subqual {
159 my ($self) = @_;
161 if( $self->can('throw') ) {
162 $self->throw("Bio::Seq::QualI definition of subqual - implementing class did not provide this method");
163 } else {
164 confess("Bio::Seq::QualI definition of subqual - implementing class did not provide this method");
169 =head2 display_id()
171 Title : display_id()
172 Usage : $id_string = $obj->display_id() _or_
173 $id_string = $obj->display_id($new_display_id);
174 Function: Returns the display id, aka the common name of the Quality
175 object.
176 The semantics of this is that it is the most likely string to be
177 used as an identifier of the quality sequence, and likely to have
178 "human" readability. The id is equivalent to the ID field of the
179 GenBank/EMBL databanks and the id field of the Swissprot/sptrembl
180 database. In fasta format, the >(\S+) is presumed to be the id,
181 though some people overload the id to embed other information.
182 Bioperl does not use any embedded information in the ID field,
183 and people are encouraged to use other mechanisms (accession field
184 for example, or extending the sequence object) to solve this.
185 Notice that $seq->id() maps to this function, mainly for
186 legacy/convience issues
187 Returns : A string
188 Args : If an arg is provided, it will replace the existing display_id
189 in the object.
192 =cut
194 sub display_id {
195 my ($self) = @_;
197 if( $self->can('throw') ) {
198 $self->throw("Bio::Seq::QualI definition of id - implementing class did not provide this method");
199 } else {
200 confess("Bio::Seq::QualI definition of id - implementing class did not provide this method");
206 =head2 accession_number()
208 Title : accession_number()
209 Usage : $unique_biological_key = $obj->accession_number(); _or_
210 $unique_biological_key = $obj->accession_number($new_acc_num);
211 Function: Returns the unique biological id for a sequence, commonly
212 called the accession_number. For sequences from established
213 databases, the implementors should try to use the correct
214 accession number. Notice that primary_id() provides the unique id
215 for the implemetation, allowing multiple objects to have the same
216 accession number in a particular implementation. For sequences
217 with no accession number, this method should return "unknown".
218 Returns : A string.
219 Args : If an arg is provided, it will replace the existing
220 accession_number in the object.
222 =cut
224 sub accession_number {
225 my ($self,@args) = @_;
227 if( $self->can('throw') ) {
228 $self->throw("Bio::Seq::QualI definition of seq - implementing class did not provide this method");
229 } else {
230 confess("Bio::Seq::QualI definition of seq - implementing class did not provide this method");
237 =head2 primary_id()
239 Title : primary_id()
240 Usage : $unique_implementation_key = $obj->primary_id(); _or_
241 $unique_implementation_key = $obj->primary_id($new_prim_id);
242 Function: Returns the unique id for this object in this implementation.
243 This allows implementations to manage their own object ids in a
244 way the implementaiton can control clients can expect one id to
245 map to one object. For sequences with no accession number, this
246 method should return a stringified memory location.
247 Returns : A string
248 Args : If an arg is provided, it will replace the existing
249 primary_id in the object.
251 =cut
253 sub primary_id {
254 my ($self,@args) = @_;
256 if( $self->can('throw') ) {
257 $self->throw("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
258 } else {
259 confess("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
265 =head2 can_call_new()
267 Title : can_call_new()
268 Usage : if( $obj->can_call_new ) {
269 $newobj = $obj->new( %param );
271 Function: can_call_new returns 1 or 0 depending on whether an
272 implementation allows new constructor to be called. If a new
273 constructor is allowed, then it should take the followed hashed
274 constructor list.
275 $myobject->new( -qual => $quality_as_string,
276 -display_id => $id,
277 -accession_number => $accession,
279 Example :
280 Returns : 1 or 0
281 Args :
284 =cut
286 sub can_call_new{
287 my ($self,@args) = @_;
288 # we default to 0 here
289 return 0;
292 =head2 qualat($position)
294 Title : qualat($position)
295 Usage : $quality = $obj->qualat(10);
296 Function: Return the quality value at the given location, where the
297 first value is 1 and the number is inclusive, ie 1-2 are the first
298 two bases of the sequence. Start cannot be larger than end but can
299 be equal.
300 Returns : A scalar.
301 Args : A position.
303 =cut
305 sub qualat {
306 my ($self,$value) = @_;
307 if( $self->can('warn') ) {
308 $self->warn("Bio::Seq::QualI definition of qualat - implementing class did not provide this method");
309 } else {
310 warn("Bio::Seq::QualI definition of qualat - implementing class did not provide this method");
312 return '';
315 =head1 Optional Implementation Functions
317 The following functions rely on the above functions. A implementing
318 class does not need to provide these functions, as they will be
319 provided by this class, but is free to override these functions.
321 All of revcom(), trunc(), and translate() create new sequence
322 objects. They will call new() on the class of the sequence object
323 instance passed as argument, unless can_call_new() returns FALSE. In
324 the latter case a Bio::PrimarySeq object will be created. Implementors
325 which really want to control how objects are created (eg, for object
326 persistence over a database, or objects in a CORBA framework), they
327 are encouraged to override these methods
329 =head2 revcom
331 Title : revcom
332 Usage : @rev = @{$qual->revcom()};
333 Function: Produces a new Bio::Seq::QualI implementing object which
334 is reversed from the original quality array.
335 The id is the same id as the orginal sequence, and the accession number
336 is also indentical. If someone wants to track that this sequence has
337 been reversed, it needs to define its own extensions
339 To do an inplace edit of an object you can go:
341 $qual = $qual->revcom();
343 This of course, causes Perl to handle the garbage collection of the old
344 object, but it is roughly speaking as efficient as an inplace edit.
345 Returns : A new (fresh) Bio::Seq::PrimaryQualI object
346 Args : none
348 =cut
350 sub revcom{
351 my ($self) = @_;
352 # this is the cleanest way
353 my @qualities = @{$self->qual()};
354 my @reversed_qualities = reverse(@qualities);
355 my $seqclass;
356 if($self->can_call_new()) {
357 $seqclass = ref($self);
358 } else {
359 $seqclass = 'Bio::Seq::PrimaryQual';
360 # Wassat?
361 # $self->_attempt_to_load_Seq();
363 # the \@reverse_qualities thing works simply because I will it to work.
364 my $out = $seqclass->new( '-qual' => \@reversed_qualities,
365 '-display_id' => $self->display_id,
366 '-accession_number' => $self->accession_number,
367 '-desc' => $self->desc()
369 return $out;
372 =head2 trunc()
374 Title : trunc
375 Usage : $subseq = $myseq->trunc(10,100);
376 Function: Provides a truncation of a sequence,
377 Returns : a fresh Bio::Seq::QualI implementing object
378 Args : Two integers denoting first and last base of the sub-sequence.
381 =cut
383 sub trunc {
384 my ($self,$start,$end) = @_;
386 if( !$end ) {
387 if( $self->can('throw') ) {
388 $self->throw("trunc start,end");
389 } else {
390 confess("[$self] trunc start,end");
394 if( $end < $start ) {
395 if( $self->can('throw') ) {
396 $self->throw("$end is smaller than $start. if you want to truncated and reverse complement, you must call trunc followed by revcom. Sorry.");
397 } else {
398 confess("[$self] $end is smaller than $start. If you want to truncated and reverse complement, you must call trunc followed by revcom. Sorry.");
402 my $r_qual = $self->subqual($start,$end);
404 my $seqclass;
405 if($self->can_call_new()) {
406 $seqclass = ref($self);
407 } else {
408 $seqclass = 'Bio::Seq::PrimaryQual';
409 # wassat?
410 # $self->_attempt_to_load_Seq();
412 my $out = $seqclass->new( '-qual' => $r_qual,
413 '-display_id' => $self->display_id,
414 '-accession_number' => $self->accession_number,
415 '-desc' => $self->desc()
417 return $out;
421 =head2 translate()
423 Title : translate()
424 Usage : $protein_seq_obj = $dna_seq_obj->translate
425 #if full CDS expected:
426 $protein_seq_obj = $cds_seq_obj->translate(undef,undef,undef,undef,1);
427 Function: Completely useless in this interface.
428 Returns : Nothing.
429 Args : Nothing.
431 =cut
434 sub translate {
435 return 0;
439 =head2 id()
441 Title : id()
442 Usage : $id = $qual->id()
443 Function: ID of the quality. This should normally be (and actually is in
444 the implementation provided here) just a synonym for display_id().
445 Example :
446 Returns : A string.
447 Args :
450 =cut
452 sub id {
453 my ($self)= @_;
454 return $self->display_id();
457 =head2 length()
459 Title : length()
460 Usage : $length = $qual->length();
461 Function: Return the length of the array holding the quality values.
462 Under most circumstances, this should match the number of quality
463 values but no validation is done when the PrimaryQual object is
464 constructed and non-digits could be put into this array. Is this a
465 bug? Just enough rope...
466 Returns : A scalar (the number of elements in the quality array).
467 Args : None.
469 =cut
471 sub length {
472 my ($self)= @_;
473 if( $self->can('throw') ) {
474 $self->throw("Bio::Seq::QualI definition of length - implementing class did not provide this method");
475 } else {
476 confess("Bio::Seq::QualI definition of length - implementing class did not provide this method");
481 =head2 desc()
483 Title : desc()
484 Usage : $qual->desc($newval);
485 $description = $seq->desc();
486 Function: Get/set description text for a qual object
487 Example :
488 Returns : value of desc
489 Args : newvalue (optional)
491 =cut
493 sub desc {
494 my ($self,$value) = @_;
495 if( $self->can('warn') ) {
496 $self->warn("Bio::Seq::QualI definition of desc - implementing class did not provide this method");
497 } else {
498 warn("Bio::Seq::QualI definition of desc - implementing class did not provide this method");
500 return '';
503 # These methods are here for backward compatibility with the old, 0.5
504 # Seq objects. They all throw warnings that someone is using a
505 # deprecated method, and may eventually be removed completely from
506 # this object. However, they are important to ease the transition from
507 # the old system.
509 =head1 Private functions
511 These are some private functions for the PrimarySeqI interface. You do not
512 need to implement these functions
514 =head2 _attempt_to_load_Seq
516 Title : _attempt_to_load_Seq
517 Usage :
518 Function:
519 Example :
520 Returns :
521 Args :
524 =cut
526 sub _attempt_to_load_Seq{
527 my ($self) = @_;
529 if( $main::{'Bio::Seq::PrimaryQual'} ) {
530 return 1;
531 } else {
532 eval {
533 require Bio::Seq::PrimaryQual;
535 if( $@ ) {
536 if( $self->can('throw') ) {
537 $self->throw("Bio::Seq::PrimaryQual could not be loaded for $self\nThis indicates that you are using Bio::Seq::PrimaryQualI without Bio::Seq::PrimaryQual loaded and without providing a complete solution\nThe most likely problem is that there has been a misconfiguration of the bioperl environment\nActual exception\n\n$@\n");
538 } else {
539 confess("Bio::Seq::PrimarySeq could not be loaded for $self\nThis indicates that you are usnig Bio::Seq::PrimaryQualI without Bio::Seq::PrimaryQual loaded and without providing a complete solution\nThe most likely problem is that there has been a misconfiguration of the bioperl environment\nActual exception\n\n$@\n");
541 return 0;
543 return 1;
549 =head2 qualtype()
551 Title : qualtype()
552 Usage : if( $obj->qualtype eq 'phd' ) { /Do Something/ }
553 Function: At this time, this function is not used for
554 Bio::Seq::PrimaryQual objects. In fact, now it is a month later and
555 I just completed the Bio::Seq::SeqWithQuality object and this is
556 definitely deprecated.
557 Returns : Nothing. (not implemented)
558 Args : none
559 Status : Virtual
562 =cut
564 sub qualtype {
565 my ($self,@args) = @_;
566 if( $self->can('throw') ) {
567 # $self->throw("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
568 $self->throw("qualtypetype is not used with quality objects.");
569 } else {
570 # confess("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
571 confess("qualtype is not used with quality objects.");