File Coverage

blib/lib/Bio/Gonzales/Align/IO.pm
Criterion Covered Total %
statement 71 93 76.3
branch 14 24 58.3
condition n/a
subroutine 11 12 91.6
pod 1 2 50.0
total 97 131 74.0


line stmt bran cond sub pod time code
1             package Bio::Gonzales::Align::IO;
2              
3 1     1   14513 use warnings;
  1         3  
  1         36  
4 1     1   6 use strict;
  1         2  
  1         19  
5 1     1   5 use Carp;
  1         3  
  1         55  
6              
7 1     1   6 use Bio::Gonzales::Seq;
  1         2  
  1         24  
8              
9 1     1   17 use Bio::Gonzales::Util::File qw/open_on_demand/;
  1         8  
  1         65  
10 1     1   9 use Bio::Gonzales::Util qw/flatten/;
  1         2  
  1         45  
11 1     1   8 use base 'Exporter';
  1         2  
  1         1260  
12             our ( @EXPORT, @EXPORT_OK, %EXPORT_TAGS );
13             our $VERSION = '0.083'; # VERSION
14              
15             @EXPORT = qw();
16             %EXPORT_TAGS = ();
17             @EXPORT_OK = qw(phylip_spew phylip_slurp);
18              
19             sub phylip_spew {
20 3     3 1 39 my ( $file_or_fh, $mode, @rest ) = @_;
21 3         16 my @seqs = flatten(@rest);
22              
23 3         10 my ( $fh, $fh_was_open ) = open_on_demand( $file_or_fh, '>' );
24 3 100       13 if ( ref $mode eq 'HASH' ) {
25 2 50       7 if ( $mode->{sequential} ) {
26 2         9 _seq_phylip_spew( $fh, \@seqs, $mode->{relaxed} );
27             } else {
28 0         0 confess 'function not implemented, yet';
29             }
30              
31             } else {
32 1         8 my $relaxed = $mode =~ s/^r(?:elax(?:ed)?)?\W//;
33 1 50       6 if ( $mode =~ /^s(?:eq(?:uential)?)?$/ ) {
34 1         5 _seq_phylip_spew( $fh, \@seqs, $relaxed );
35             } else {
36 0         0 croak "you have to supply a mode";
37             }
38             }
39              
40 3 50       13 $fh->close unless ($fh_was_open);
41             }
42              
43             sub _seq_phylip_spew {
44 3     3   45 my ( $fh, $seqs, $relaxed ) = @_;
45              
46 3 50       11 croak "You have to supply an array of Bio::Gonzales::Seq objects"
47             unless ( ref $seqs eq 'ARRAY' );
48              
49 3         82 print $fh scalar(@$seqs) . " " . $seqs->[0]->length, "\n";
50              
51 3         11 for my $seq (@$seqs) {
52 12         18 my $id;
53 12 100       24 if ($relaxed) {
54 8         31 ( $id = $seq->id ) =~ s/\s/_/g;
55 8         14 $id .= " ";
56             } else {
57 4         22 $id = sprintf( "%-10s", substr( $seq->id, 0, 10 ) );
58             }
59 12         32 print $fh $id . $seq->seq, "\n";
60             }
61             }
62              
63             sub phylip_slurp {
64 1     1 0 852 my ( $file_or_fh, $mode ) = @_;
65              
66 1         3 my $seqs;
67 1         4 my ( $fh, $fh_was_open ) = open_on_demand( $file_or_fh, '<' );
68 1         4 my $relaxed = $mode =~ s/^r(?:elax(?:ed)?)?\W//;
69 1 50       10 if ( $mode =~ /^s(?:eq(?:uential)?)?$/ ) { $seqs = _seq_phylip_slurp( $fh, $relaxed ) }
  0 50       0  
70 1         5 elsif ( $mode =~ /^i(?:nter(?:leaved)?)?$/ ) { $seqs = _int_phylip_slurp( $fh, $relaxed ) }
71 0         0 else { croak "you have to supply a mode" }
72              
73 1 50       17 $fh->close unless ($fh_was_open);
74 1         26 return $seqs;
75             }
76              
77             sub _seq_phylip_slurp {
78 0     0   0 my ( $fh, $relaxed ) = @_;
79              
80 0         0 my $header = <$fh>;
81 0         0 $header =~ s/\r\n/\n/;
82 0         0 chomp $header;
83 0         0 my ( $taxa, $chars ) = split /\s+/, $header;
84              
85 0         0 my @seqs;
86 0         0 while ( my $line = <$fh> ) {
87 0         0 $line =~ s/\r\n/\n/;
88 0         0 chomp $line;
89              
90 0         0 my ( $id, $seq_string );
91 0 0       0 if ($relaxed) {
92 0         0 ( $id, $seq_string ) = split /\s+/, $line, 2;
93             } else {
94 0         0 ( $id, $seq_string ) = unpack( 'A10A*', $line );
95 0         0 $id =~ s/^\s*//;
96 0         0 $id =~ s/\s*$//;
97             }
98              
99 0         0 push @seqs, Bio::Gonzales::Seq->new( id => $id, seq => $seq_string );
100             }
101              
102 0         0 return \@seqs;
103             }
104              
105             sub _int_phylip_slurp {
106 1     1   4 my ( $fh, $relaxed ) = @_;
107              
108 1         562 my $header = <$fh>;
109 1         9 $header =~ s/\r\n/\n/;
110 1         4 chomp $header;
111 1         11 my ( $taxa, $chars ) = split /\s+/, $header;
112              
113 1         2 my @idseq_strings;
114 1         3 my $i = 0;
115 1         8 while ( my $line = <$fh> ) {
116 9         16 $line =~ s/\r\n/\n/;
117 9         12 chomp $line;
118 9 100       28 next if ( $line =~ /^\s*$/ );
119              
120 8         13 my $idx = $i++ % $taxa;
121              
122 8         56 $idseq_strings[$idx] .= $line;
123             }
124              
125 1         4 my @seqs;
126 1         3 for my $idseq_string (@idseq_strings) {
127 4         8 my ( $id, $seq_string );
128 4 50       10 if ($relaxed) {
129 0         0 ( $id, $seq_string ) = split /\s+/, $idseq_string, 2;
130             } else {
131 4         27 ( $id, $seq_string ) = unpack( 'A10A*', $idseq_string );
132 4         20 $id =~ s/^\s*//;
133 4         17 $id =~ s/\s*$//;
134             }
135              
136 4         43 push @seqs, Bio::Gonzales::Seq->new( id => $id, seq => $seq_string );
137             }
138              
139 1         5 return \@seqs;
140             }
141              
142             1;
143              
144             __END__
145              
146             =head1 NAME
147              
148             Bio::Gonzales::Align::Util - Utility functions for aligment stuff
149              
150             =head1 SYNOPSIS
151              
152             use Bio::Gonzales::Align::Util qw(phylip_spew);
153              
154             =head1 DESCRIPTION
155              
156             =head1 OPTIONS
157              
158             =head1 SUBROUTINES
159              
160             =over 4
161              
162             =item B<< phylip_spew($file_or_fh, $mode, $seqs) >>
163              
164             Spew out the seqs to a file or file handle. Following modes are available:
165              
166             =over 4
167              
168             =item s|seq|sequential
169              
170             Sequential format, cuts of the ID at 10 characters starting from the beginning
171              
172             =item r|relax|relaxed s|seq|sequential
173              
174             The relaxed phylip format.
175              
176             =back
177              
178             =back
179              
180             =head1 SEE ALSO
181              
182             =head1 AUTHOR
183              
184             jw bargsten, C<< <joachim.bargsten at wur.nl> >>
185              
186             =cut