add latest changes to, um, Changes
[bioperl-live.git] / Bio / Seq / QualI.pm
blob27dedbd2ee1dc0570c3eab188e38d98384ae18d2
2 # BioPerl module for Bio::Seq::QualI
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Chad Matsalla <bioinformatics@dieselwurks.com
8 # Copyright Chad Matsalla
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::Seq::QualI - Interface definition for a Bio::Seq::Qual
18 =head1 SYNOPSIS
20 # get a Bio::Seq::Qual compliant object somehow
22 # to test this is a seq object
24 $obj->isa("Bio::Seq::QualI")
25 || $obj->throw("$obj does not implement the Bio::Seq::QualI interface");
27 # accessors
29 $string = $obj->qual();
30 $substring = $obj->subqual(12,50);
31 $display = $obj->display_id(); # for human display
32 $id = $obj->primary_id(); # unique id for this object,
33 # implementation defined
34 $unique_key= $obj->accession_number();
35 # unique biological id
39 =head1 DESCRIPTION
41 This object defines an abstract interface to basic quality
42 information. PrimaryQual is an object just for the quality and its
43 name(s), nothing more. There is a pure perl implementation of this in
44 Bio::Seq::PrimaryQual. If you just want to use Bio::Seq::PrimaryQual
45 objects, then please read that module first. This module defines the
46 interface, and is of more interest to people who want to wrap their
47 own Perl Objects/RDBs/FileSystems etc in way that they "are" bioperl
48 quality objects, even though it is not using Perl to store the
49 sequence etc.
51 This interface defines what bioperl consideres necessary to "be" a
52 sequence of qualities, without providing an implementation of
53 this. (An implementation is provided in Bio::Seq::PrimaryQual). If you
54 want to provide a Bio::Seq::PrimaryQual 'compliant' object which in
55 fact wraps another object/database/out-of-perl experience, then this
56 is the correct thing to wrap, generally by providing a wrapper class
57 which would inherit from your object and this Bio::Seq::QualI
58 interface. The wrapper class then would have methods lists in the
59 "Implementation Specific Functions" which would provide these methods
60 for your object.
63 =head1 FEEDBACK
65 =head2 Mailing Lists
67 User feedback is an integral part of the evolution of this and other
68 Bioperl modules. Send your comments and suggestions preferably to one
69 of the Bioperl mailing lists. Your participation is much appreciated.
71 bioperl-l@bioperl.org - General discussion
72 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
74 =head2 Support
76 Please direct usage questions or support issues to the mailing list:
78 I<bioperl-l@bioperl.org>
80 rather than to the module maintainer directly. Many experienced and
81 reponsive experts will be able look at the problem and quickly
82 address it. Please include a thorough description of the problem
83 with code and data examples if at all possible.
85 =head2 Reporting Bugs
87 Report bugs to the Bioperl bug tracking system to help us keep track
88 the bugs and their resolution. Bug reports can be submitted via the
89 web:
91 https://github.com/bioperl/bioperl-live/issues
93 =head1 AUTHOR - Chad Matsalla
95 This module is heavily based on Bio::Seq::PrimarySeq and is modeled after
96 or outright copies sections of it. Thanks Ewan!
98 Email bioinformatics@dieselwurks.com
100 =head1 APPENDIX
102 The rest of the documentation details each of the object methods.
103 Internal methods are usually preceded with a _
105 =cut
108 # Let the code begin...
111 package Bio::Seq::QualI;
112 use strict;
113 use Carp;
115 use base qw(Bio::Root::RootI);
117 =head1 Implementation Specific Functions
119 These functions are the ones that a specific implementation must
120 define.
122 =head2 qual()
124 Title : qual()
125 Usage : @quality_values = @{$obj->qual()};
126 Function: Returns the quality as a reference to an array containing the
127 quality values. The individual elements of the quality array are
128 not validated and can be any numeric value.
129 Returns : A reference to an array.
130 Status :
132 =cut
134 sub qual {
135 my ($self) = @_;
136 if( $self->can('throw') ) {
137 $self->throw("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
138 } else {
139 confess("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
143 =head2 subqual($start,$end)
145 Title : subqual($start,$end)
146 Usage : @subset_of_quality_values = @{$obj->subseq(10,40)};
147 Function: returns the quality values from $start to $end, where the
148 first value is 1 and the number is inclusive, ie 1-2 are the first
149 two bases of the sequence. Start cannot be larger than end but can
150 be equal.
151 Returns : A reference to an array.
152 Args : a start position and an end position
155 =cut
157 sub subqual {
158 my ($self) = @_;
160 if( $self->can('throw') ) {
161 $self->throw("Bio::Seq::QualI definition of subqual - implementing class did not provide this method");
162 } else {
163 confess("Bio::Seq::QualI definition of subqual - implementing class did not provide this method");
168 =head2 display_id()
170 Title : display_id()
171 Usage : $id_string = $obj->display_id() _or_
172 $id_string = $obj->display_id($new_display_id);
173 Function: Returns the display id, aka the common name of the Quality
174 object.
175 The semantics of this is that it is the most likely string to be
176 used as an identifier of the quality sequence, and likely to have
177 "human" readability. The id is equivalent to the ID field of the
178 GenBank/EMBL databanks and the id field of the Swissprot/sptrembl
179 database. In fasta format, the >(\S+) is presumed to be the id,
180 though some people overload the id to embed other information.
181 Bioperl does not use any embedded information in the ID field,
182 and people are encouraged to use other mechanisms (accession field
183 for example, or extending the sequence object) to solve this.
184 Notice that $seq->id() maps to this function, mainly for
185 legacy/convience issues
186 Returns : A string
187 Args : If an arg is provided, it will replace the existing display_id
188 in the object.
191 =cut
193 sub display_id {
194 my ($self) = @_;
196 if( $self->can('throw') ) {
197 $self->throw("Bio::Seq::QualI definition of id - implementing class did not provide this method");
198 } else {
199 confess("Bio::Seq::QualI definition of id - implementing class did not provide this method");
205 =head2 accession_number()
207 Title : accession_number()
208 Usage : $unique_biological_key = $obj->accession_number(); _or_
209 $unique_biological_key = $obj->accession_number($new_acc_num);
210 Function: Returns the unique biological id for a sequence, commonly
211 called the accession_number. For sequences from established
212 databases, the implementors should try to use the correct
213 accession number. Notice that primary_id() provides the unique id
214 for the implemetation, allowing multiple objects to have the same
215 accession number in a particular implementation. For sequences
216 with no accession number, this method should return "unknown".
217 Returns : A string.
218 Args : If an arg is provided, it will replace the existing
219 accession_number in the object.
221 =cut
223 sub accession_number {
224 my ($self,@args) = @_;
226 if( $self->can('throw') ) {
227 $self->throw("Bio::Seq::QualI definition of seq - implementing class did not provide this method");
228 } else {
229 confess("Bio::Seq::QualI definition of seq - implementing class did not provide this method");
236 =head2 primary_id()
238 Title : primary_id()
239 Usage : $unique_implementation_key = $obj->primary_id(); _or_
240 $unique_implementation_key = $obj->primary_id($new_prim_id);
241 Function: Returns the unique id for this object in this implementation.
242 This allows implementations to manage their own object ids in a
243 way the implementaiton can control clients can expect one id to
244 map to one object. For sequences with no accession number, this
245 method should return a stringified memory location.
246 Returns : A string
247 Args : If an arg is provided, it will replace the existing
248 primary_id in the object.
250 =cut
252 sub primary_id {
253 my ($self,@args) = @_;
255 if( $self->can('throw') ) {
256 $self->throw("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
257 } else {
258 confess("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
264 =head2 can_call_new()
266 Title : can_call_new()
267 Usage : if( $obj->can_call_new ) {
268 $newobj = $obj->new( %param );
270 Function: can_call_new returns 1 or 0 depending on whether an
271 implementation allows new constructor to be called. If a new
272 constructor is allowed, then it should take the followed hashed
273 constructor list.
274 $myobject->new( -qual => $quality_as_string,
275 -display_id => $id,
276 -accession_number => $accession,
278 Example :
279 Returns : 1 or 0
280 Args :
283 =cut
285 sub can_call_new{
286 my ($self,@args) = @_;
287 # we default to 0 here
288 return 0;
291 =head2 qualat($position)
293 Title : qualat($position)
294 Usage : $quality = $obj->qualat(10);
295 Function: Return the quality value at the given location, where the
296 first value is 1 and the number is inclusive, ie 1-2 are the first
297 two bases of the sequence. Start cannot be larger than end but can
298 be equal.
299 Returns : A scalar.
300 Args : A position.
302 =cut
304 sub qualat {
305 my ($self,$value) = @_;
306 if( $self->can('warn') ) {
307 $self->warn("Bio::Seq::QualI definition of qualat - implementing class did not provide this method");
308 } else {
309 warn("Bio::Seq::QualI definition of qualat - implementing class did not provide this method");
311 return '';
314 =head1 Optional Implementation Functions
316 The following functions rely on the above functions. A implementing
317 class does not need to provide these functions, as they will be
318 provided by this class, but is free to override these functions.
320 All of revcom(), trunc(), and translate() create new sequence
321 objects. They will call new() on the class of the sequence object
322 instance passed as argument, unless can_call_new() returns FALSE. In
323 the latter case a Bio::PrimarySeq object will be created. Implementors
324 which really want to control how objects are created (eg, for object
325 persistence over a database, or objects in a CORBA framework), they
326 are encouraged to override these methods
328 =head2 revcom
330 Title : revcom
331 Usage : @rev = @{$qual->revcom()};
332 Function: Produces a new Bio::Seq::QualI implementing object which
333 is reversed from the original quality array.
334 The id is the same id as the orginal sequence, and the accession number
335 is also indentical. If someone wants to track that this sequence has
336 been reversed, it needs to define its own extensions
338 To do an inplace edit of an object you can go:
340 $qual = $qual->revcom();
342 This of course, causes Perl to handle the garbage collection of the old
343 object, but it is roughly speaking as efficient as an inplace edit.
344 Returns : A new (fresh) Bio::Seq::PrimaryQualI object
345 Args : none
347 =cut
349 sub revcom{
350 my ($self) = @_;
351 # this is the cleanest way
352 my @qualities = @{$self->qual()};
353 my @reversed_qualities = reverse(@qualities);
354 my $seqclass;
355 if($self->can_call_new()) {
356 $seqclass = ref($self);
357 } else {
358 $seqclass = 'Bio::Seq::PrimaryQual';
359 # Wassat?
360 # $self->_attempt_to_load_Seq();
362 # the \@reverse_qualities thing works simply because I will it to work.
363 my $out = $seqclass->new( '-qual' => \@reversed_qualities,
364 '-display_id' => $self->display_id,
365 '-accession_number' => $self->accession_number,
366 '-desc' => $self->desc()
368 return $out;
371 =head2 trunc()
373 Title : trunc
374 Usage : $subseq = $myseq->trunc(10,100);
375 Function: Provides a truncation of a sequence,
376 Returns : a fresh Bio::Seq::QualI implementing object
377 Args : Two integers denoting first and last base of the sub-sequence.
380 =cut
382 sub trunc {
383 my ($self,$start,$end) = @_;
385 if( !$end ) {
386 if( $self->can('throw') ) {
387 $self->throw("trunc start,end");
388 } else {
389 confess("[$self] trunc start,end");
393 if( $end < $start ) {
394 if( $self->can('throw') ) {
395 $self->throw("$end is smaller than $start. if you want to truncated and reverse complement, you must call trunc followed by revcom. Sorry.");
396 } else {
397 confess("[$self] $end is smaller than $start. If you want to truncated and reverse complement, you must call trunc followed by revcom. Sorry.");
401 my $r_qual = $self->subqual($start,$end);
403 my $seqclass;
404 if($self->can_call_new()) {
405 $seqclass = ref($self);
406 } else {
407 $seqclass = 'Bio::Seq::PrimaryQual';
408 # wassat?
409 # $self->_attempt_to_load_Seq();
411 my $out = $seqclass->new( '-qual' => $r_qual,
412 '-display_id' => $self->display_id,
413 '-accession_number' => $self->accession_number,
414 '-desc' => $self->desc()
416 return $out;
420 =head2 translate()
422 Title : translate()
423 Usage : $protein_seq_obj = $dna_seq_obj->translate
424 #if full CDS expected:
425 $protein_seq_obj = $cds_seq_obj->translate(undef,undef,undef,undef,1);
426 Function: Completely useless in this interface.
427 Returns : Nothing.
428 Args : Nothing.
430 =cut
433 sub translate {
434 return 0;
438 =head2 id()
440 Title : id()
441 Usage : $id = $qual->id()
442 Function: ID of the quality. This should normally be (and actually is in
443 the implementation provided here) just a synonym for display_id().
444 Example :
445 Returns : A string.
446 Args :
449 =cut
451 sub id {
452 my ($self)= @_;
453 return $self->display_id();
456 =head2 length()
458 Title : length()
459 Usage : $length = $qual->length();
460 Function: Return the length of the array holding the quality values.
461 Under most circumstances, this should match the number of quality
462 values but no validation is done when the PrimaryQual object is
463 constructed and non-digits could be put into this array. Is this a
464 bug? Just enough rope...
465 Returns : A scalar (the number of elements in the quality array).
466 Args : None.
468 =cut
470 sub length {
471 my ($self)= @_;
472 if( $self->can('throw') ) {
473 $self->throw("Bio::Seq::QualI definition of length - implementing class did not provide this method");
474 } else {
475 confess("Bio::Seq::QualI definition of length - implementing class did not provide this method");
480 =head2 desc()
482 Title : desc()
483 Usage : $qual->desc($newval);
484 $description = $seq->desc();
485 Function: Get/set description text for a qual object
486 Example :
487 Returns : value of desc
488 Args : newvalue (optional)
490 =cut
492 sub desc {
493 my ($self,$value) = @_;
494 if( $self->can('warn') ) {
495 $self->warn("Bio::Seq::QualI definition of desc - implementing class did not provide this method");
496 } else {
497 warn("Bio::Seq::QualI definition of desc - implementing class did not provide this method");
499 return '';
502 # These methods are here for backward compatibility with the old, 0.5
503 # Seq objects. They all throw warnings that someone is using a
504 # deprecated method, and may eventually be removed completely from
505 # this object. However, they are important to ease the transition from
506 # the old system.
508 =head1 Private functions
510 These are some private functions for the PrimarySeqI interface. You do not
511 need to implement these functions
513 =head2 _attempt_to_load_Seq
515 Title : _attempt_to_load_Seq
516 Usage :
517 Function:
518 Example :
519 Returns :
520 Args :
523 =cut
525 sub _attempt_to_load_Seq{
526 my ($self) = @_;
528 if( $main::{'Bio::Seq::PrimaryQual'} ) {
529 return 1;
530 } else {
531 eval {
532 require Bio::Seq::PrimaryQual;
534 if( $@ ) {
535 if( $self->can('throw') ) {
536 $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");
537 } else {
538 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");
540 return 0;
542 return 1;
548 =head2 qualtype()
550 Title : qualtype()
551 Usage : if( $obj->qualtype eq 'phd' ) { /Do Something/ }
552 Function: At this time, this function is not used for
553 Bio::Seq::PrimaryQual objects. In fact, now it is a month later and
554 I just completed the Bio::Seq::SeqWithQuality object and this is
555 definitely deprecated.
556 Returns : Nothing. (not implemented)
557 Args : none
558 Status : Virtual
561 =cut
563 sub qualtype {
564 my ($self,@args) = @_;
565 if( $self->can('throw') ) {
566 # $self->throw("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
567 $self->throw("qualtypetype is not used with quality objects.");
568 } else {
569 # confess("Bio::Seq::QualI definition of qual - implementing class did not provide this method");
570 confess("qualtype is not used with quality objects.");