File Coverage

blib/lib/Bio/Align/Subset.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Bio::Align::Subset;
2              
3              
4 1     1   34033 use 5.006;
  1         4  
  1         39  
5 1     1   6 use strict;
  1         2  
  1         33  
6 1     1   4 no strict "refs";
  1         14  
  1         28  
7 1     1   5 use warnings;
  1         3  
  1         52  
8 1     1   90 use Carp;
  1         2  
  1         87  
9 1     1   434 use Bio::SeqIO;
  0            
  0            
10              
11             use base("Bio::Root::Root");
12              
13             =head1 NAME
14              
15             Bio::Align::Subset - A BioPerl module to generate new alignments as subset from larger alignments
16              
17             =head1 VERSION
18              
19             Version 1.27
20              
21             =cut
22              
23             our $VERSION = '1.27';
24              
25              
26             =head1 SYNOPSIS
27            
28             use strict;
29             use warnings;
30             use Data::Dumper;
31            
32             use Bio::Align::Subset;
33            
34             # The alignment in a file
35             my $filename = "alignmentfile.fas";
36             # The format
37             my $format = "fasta";
38            
39             # The subset of codons
40             my $subset = [1,12,25,34,65,100,153,156,157,158,159,160,200,201,202,285];
41            
42             # Create the object
43             my $obj = Bio::Align::Subset->new(
44             file => $filename,
45             format => $format
46             );
47            
48             # View the result
49             # This function returns a Bio::SimpleAlign object
50             print Dumper($obj->build_subset($subset));
51              
52             =cut
53              
54             =head1 DESCRIPTION
55              
56             Given an array of codon positions and an alignment, the function
57             Lbuild_subset> returns a new alignment with the codons at
58             those positions from the original alignment.
59              
60             =cut
61              
62             # Body ########################################################################
63             ###############################################################################
64             ###############################################################################
65             ###############################################################################
66              
67             =head1 CONSTRUCTOR
68              
69             =head2 Bio::Align::Subset->new()
70              
71             $Obj = Bio::Align::Subset->new(file => 'filename', format => 'format')
72              
73             The L class method constructs a new L object.
74             The returned object can be used to retrieve, print and generate subsets
75             from alignment objects. L accepts the following parameters:
76              
77             =over 1
78              
79             =item file
80              
81             A file path to be opened for reading or writing. The usual Perl
82             conventions apply:
83              
84             'file' # open file for reading
85             '>file' # open file for writing
86             '>>file' # open file for appending
87             '+
88             'command |' # open a pipe from the command
89             '| command' # open a pipe to the command
90              
91             =item format
92              
93             Specify the format of the file. Supported formats include fasta,
94             genbank, embl, swiss (SwissProt), Entrez Gene and tracefile formats
95             such as abi (ABI) and scf. There are many more, for a complete listing
96             see the SeqIO HOWTO (L).
97              
98             If no format is specified and a filename is given then the module will
99             attempt to deduce the format from the filename suffix. If there is no
100             suffix that Bioperl understands then it will attempt to guess the
101             format based on file content. If this is unsuccessful then SeqIO will
102             throw a fatal error.
103              
104             The format name is case-insensitive: 'FASTA', 'Fasta' and 'fasta' are
105             all valid.
106              
107             Currently, the tracefile formats (except for SCF) require installation
108             of the external Staden "io_lib" package, as well as the
109             Bio::SeqIO::staden::read package available from the bioperl-ext
110             repository.
111              
112             =back
113              
114             =cut
115              
116             ###############################################################################
117             # Class data and methods
118             ###############################################################################
119             {
120             # A list of all attributes wiht default values and read/write/required properties
121             my %_attribute_properties = (
122             _file => ["????", "read.required"],
123             _format => ["????", "read.required"],
124             _identifiers => ["????", "read.write" ],
125             _sequences => ["????", "read.write" ],
126             _seq_length=> [0 , "read.write" ]
127             );
128            
129             # Global variable to keep count of existing objects
130             my $_count = 0;
131            
132             # The list of all attributes
133             sub _all_attributes {
134             keys %_attribute_properties;
135             }
136            
137             # Check if a given property is set for a given attribute
138             sub _permissions{
139             my ($self,$attribute, $permissions) = @_;
140             $_attribute_properties{$attribute}[1] =~/$permissions/;
141             }
142            
143             # Return the default value for a given attribute
144             sub _attribute_default{
145             my ($self,$attribute) = @_;
146             $_attribute_properties{$attribute}[0];
147             }
148            
149             # Manage the count of existing objects
150             sub get_count{
151             $_count;
152             }
153             sub _incr_count{
154             ++$_count;
155             }
156             sub _decr_count{
157             --$_count;
158             }
159            
160             }
161             #
162             # The constructor of the class
163             #
164             sub new {
165            
166             my ($class, %arg) = @_;
167             my $self = bless {}, $class;
168            
169             foreach my $attribute ($self->_all_attributes()){
170            
171             # E.g. attribute = "_name", argument = "name"
172             my ($argument) = ($attribute =~ /^_(.*)/);
173            
174             # If explicitly given
175             if(exists $arg{$argument}){
176             $self->{$attribute} = $arg{$argument};
177             }
178            
179             # If not given but required
180             elsif($self->_permissions($attribute, 'required')){
181             croak("No $argument attribute as required");
182             }
183            
184             # Set to default
185             else{
186             $self->{$attribute} = $self->_attribute_default($attribute);
187             }
188            
189             }
190            
191             # Called $class because it is a gobal method
192             $class->_incr_count;
193            
194             $self->_extract_sequences;
195             return $self;
196            
197             }
198              
199              
200             #
201             # Obtaining the sequences in a Array
202             #
203             sub _extract_sequences{
204            
205             my $self = $_[0];
206            
207             my @identifiers;
208             my @sequences;
209            
210             my $seqIO = Bio::SeqIO->new(
211             -file => $self->get_file,
212             -format => $self->get_format
213             );
214            
215             while( my $seq = $seqIO->next_seq){
216            
217             my $sequence_string = $seq->seq;
218             $sequence_string =~ s/\s//g;
219            
220             push(@identifiers, $seq->id);
221             $self->_verify_chain($sequence_string);
222             push(@sequences, $sequence_string);
223            
224             }
225            
226             $self->set_identifiers(\@identifiers);
227             $self->set_sequences(\@sequences);
228            
229             }
230              
231             =head1 OBJECT METHODS
232              
233             =head2 build_subset($index_list)
234              
235             my $subset = $obj->build_subset([1,12,25,34,65,100,153,156,157,158,159]);
236              
237             Build a new alignment with the specified codons in C<$index_list>. It returns
238             a L object.
239              
240              
241             =cut
242              
243             #
244             # Build a subset
245             #
246             sub build_subset{
247            
248             my ($self, $subset) = @_;
249            
250            
251             # Initialite array for the new sequences
252             my @new_sequences = ();
253            
254             for(my $i=0;$i<=$#{$self->get_sequences};$i++){
255             # Initialite a new string for the new sequence
256             my $new_sequence = "";
257             for my $index (@{$subset}){
258             if(($index-1)*3 > length(${$self->get_sequences}[$i])){ last }
259             $new_sequence.= substr(${$self->get_sequences}[$i],($index-1)*3,3);
260             }
261             push(@new_sequences, $new_sequence);
262             }
263            
264             my @identifiers = @{$self->get_identifiers};
265             # Create the new align object
266             my $aln_obj = Bio::SimpleAlign->new();
267            
268             # Build a new Bio::LocatableSeq obj for each sequence
269             for(my $i=0;$i<=$#identifiers;$i++){
270            
271             my $id = substr($identifiers[$i],0,9);
272             my $iden_plus_num = $i.$id;
273            
274             # Create such object
275             my $newSeq = Bio::LocatableSeq->new(-seq => $new_sequences[$i],
276             -id => substr($iden_plus_num,0,9),
277             -start => 0,
278             -end => length($new_sequences[$i]));
279            
280             # Append the new sequence object to the new alignmen object
281             $aln_obj->add_seq($newSeq);
282            
283             }
284            
285             # Once the loop is finished, return the alignment object
286             # with all the sequences appended.
287             return $aln_obj;
288            
289             }
290              
291             ###############################################################################
292             # Auxiliary methods
293             ###############################################################################
294             {
295             #
296             # Set the sequence length of the whole alignment
297             #
298             sub _set_sequence_length{
299             my $self = $_[0];
300             $self->{_seq_length} = $_[1];
301             }
302            
303             #
304             # Check if a the length of a given sequence match with the length of
305             # the whole alignment.
306             #
307             sub _check_sequence_length{
308             my $self = $_[0];
309             my $tested_sequence_length = $_[1];
310             $tested_sequence_length == $self->get_seq_length ? return 1 : return 0;
311             }
312            
313             #
314             # Verifies the integrity of a given sequence
315             #
316             sub _verify_chain{
317            
318             my ($self,$sequence) = @_;
319             my $seq_length = length($sequence);
320            
321            
322             # 1. The chain must be a DNA sequence
323             $self->_isdna($sequence) ? 1 : $self->warn("\nThe following sequence does not seems as a dna/rna (ATGCU) sequence:\n\n<< $sequence >>\n");
324            
325             # 2. Also, all the sequences must be equal. But if $_sequence_length
326             # has not been updated, it takes the value of the length of this sequence.
327             if($self->get_seq_length == 0){
328             # The input file must be wrapped (non untermitated codons)
329             $seq_length % 3 == 0 ? 1 : $self->throw("The sequence length is not multiple of 3 ($seq_length)");
330             $self->_set_sequence_length($seq_length);
331             }else{
332             $self->_check_sequence_length($seq_length) ? 1 : croak("A sequence length does not match with the length of the whole alignment");
333             }
334             return 1;
335            
336             }
337            
338             #
339             # Verifies if a given string is a DNA sequence
340             #
341             sub _isdna{
342             my ($self,$sequence) = ($_[0],uc($_[1]));
343             if($sequence =~ /^[ACGTU]+$/){
344             return 1;
345             }else{
346             return 0;
347             }
348             }
349            
350            
351             }
352             ###############################################################################
353              
354              
355             ###############################################################################
356             # Accessor Methods
357             ###############################################################################
358             # This kind of method is called Accesor
359             # Method. It returns the value of a key
360             # and avoid the direct acces to the inner
361             # value of $obj->{_file}.
362             ###############################################################################
363             sub get_file { $_[0] -> {_file} }
364             sub get_format { $_[0] -> {_format} }
365             sub get_sequences { $_[0] -> {_sequences} }
366             sub get_identifiers { $_[0] -> {_identifiers} }
367             sub get_seq_length{ $_[0] -> {_seq_length}}
368             ###############################################################################
369              
370              
371             ###############################################################################
372             # Mutator Methods
373             ###############################################################################
374             sub set_file { my ($self, $file) = @_;
375             $self-> {_file} = $file if $file;
376             }
377             sub set_format { my ($self, $format) = @_;
378             $self-> {_format} = $format if $format;
379             }
380             sub set_identifiers { my ($self, $identifiers) = @_;
381             $self-> {_identifiers} = $identifiers if $identifiers;
382             }
383             sub set_sequences { my ($self, $sequences) = @_;
384             $self-> {_sequences} = $sequences if $sequences;
385             }
386             ###############################################################################
387              
388              
389              
390             # Footer ######################################################################
391             ###############################################################################
392             ###############################################################################
393             ###############################################################################
394              
395             =head1 ACCESSOR METHODS
396              
397             =head2 get_count
398              
399             Title : get_count
400             Usage : $instance_no = $obj->get_count
401             Function:
402             Returns : Number of istances for this class
403             Args :
404              
405             =head2 get_file
406              
407             Title : get_file
408             Usage : $file_path = $obj->get_file
409             Function:
410             Returns : The file name of the alignment
411             Args :
412              
413             =head2 get_format
414              
415             Title : get_format
416             Usage : $format = $obj->get_format
417             Function:
418             Returns : The alignment format (fasta, phylip, etc.)
419             Args :
420              
421             =head2 get_identifiers
422              
423             Title : get_identifiers
424             Usage : $identifiers $obj->get_identifiers
425             Function:
426             Returns : An array reference with all the identifiers in an alignment
427             Args :
428              
429             =head2 get_seq_length
430              
431             Title : get_seq_length
432             Usage : $long = $obj->get_seq_length
433             Function:
434             Returns : The longitude of all the sequences in an alignment
435             Args :
436              
437             =head2 get_sequences
438              
439             Title : get_sequences
440             Usage : $sequences = $obj->get_sequences
441             Function:
442             Returns : An array reference with all the sequences in an alignment
443             Args :
444              
445              
446             =head1 MUTATOR METHODS
447              
448             =head2 set_file
449              
450             Title : set_file
451             Usage : $obj->set_file('filename')
452             Function: Set the file path for an alignment
453             Returns :
454             Args : String
455              
456             =head2 set_format
457              
458             Title : set_format
459             Usage : $obj->set_format('fasta')
460             Function: Set the file format for an alignment
461             Returns :
462             Args : String
463              
464             =head2 set_identifiers
465              
466             Title : set_identifiers
467             Usage : $obj->set_identifiers(\@array_ids)
468             Function: Change the identifiers for all the sequences in the alignment
469             Returns :
470             Args : List
471              
472             =head2 set_sequences
473              
474             Title : set_sequences
475             Usage : $obj->set_sequences(\@array_seqs)
476             Function: Change the sequences in the alignment
477             Returns :
478             Args : List
479              
480             =head1 AUTHOR - Hector Valverde
481              
482             Hector Valverde, C<< >>
483              
484             =head1 CONTRIBUTORS
485              
486             Juan Carlos Aledo, C<< >>
487              
488             =head1 BUGS
489              
490             Please report any bugs or feature requests to C, or through
491             the web interface at L. I will be notified, and then you'll
492             automatically be notified of progress on your bug as I make changes.
493              
494              
495             =head1 SUPPORT
496              
497             You can find documentation for this module with the perldoc command.
498              
499             perldoc Bio::Align::Subset
500              
501              
502             You can also look for information at:
503              
504             =over 4
505              
506             =item * RT: CPAN's request tracker (report bugs here)
507              
508             L
509              
510             =item * AnnoCPAN: Annotated CPAN documentation
511              
512             L
513              
514             =item * CPAN Ratings
515              
516             L
517              
518             =item * Search CPAN
519              
520             L
521              
522             =back
523              
524             =head1 LICENSE AND COPYRIGHT
525              
526             Copyright 2012 Hector Valverde and Juan Carlos Aledo.
527              
528             This program is free software; you can redistribute it and/or modify it
529             under the terms of either: the GNU General Public License as published
530             by the Free Software Foundation; or the Artistic License.
531              
532             See http://dev.perl.org/licenses/ for more information.
533              
534             =cut
535              
536             1; # End of Bio::Align::Subset