File Coverage

blib/lib/GenOO/Data/File/FASTA.pm
Criterion Covered Total %
statement 44 46 95.6
branch 15 18 83.3
condition 2 3 66.6
subroutine 11 11 100.0
pod 0 1 0.0
total 72 79 91.1


line stmt bran cond sub pod time code
1             # POD documentation - main docs before the code
2              
3             =head1 NAME
4              
5             GenOO::Data::File::FASTA - Object implementing methods for accessing fasta formatted files (http://genome.ucsc.edu/FAQ/FAQformat#format1)
6              
7             =head1 SYNOPSIS
8              
9             # Object that manages a fasta file.
10              
11             # To initialize
12             my $fasta_parser = GenOO::Data::File::FASTA->new(
13             file => undef,
14             );
15              
16             =head1 DESCRIPTION
17              
18             This object offers methods to read a fasta file line by line.
19              
20             =head1 EXAMPLES
21              
22             # Create object
23             my $fasta_parser = GenOO::Data::File::FASTA->new(
24             file => 't/sample_data/sample.fasta.gz'
25             );
26              
27             # Read one record at a time
28             my $record = $fasta_parser->next_record;
29              
30             # Get the number of records read
31             my $count = $fasta_parser->records_read_count;
32              
33             =cut
34              
35             # Let the code begin...
36              
37             package GenOO::Data::File::FASTA;
38             $GenOO::Data::File::FASTA::VERSION = '1.4.6';
39              
40             #######################################################################
41             ####################### Load External modules #####################
42             #######################################################################
43 1     1   3817 use Modern::Perl;
  1         1  
  1         12  
44 1     1   170 use autodie;
  1         3  
  1         14  
45 1     1   3844 use Moose;
  1         1  
  1         12  
46 1     1   6330 use namespace::autoclean;
  1         2  
  1         12  
47              
48              
49             #######################################################################
50             ######################### Load GenOO modules ######################
51             #######################################################################
52 1     1   659 use GenOO::Data::File::FASTA::Record;
  1         4  
  1         706  
53              
54              
55             #######################################################################
56             ####################### Interface attributes ######################
57             #######################################################################
58             has 'file' => (
59             isa => 'Maybe[Str]',
60             is => 'rw',
61             required => 1
62             );
63              
64             has 'records_read_count' => (
65             is => 'rw',
66             default => 0,
67             init_arg => undef,
68             );
69              
70             has '_filehandle' => (
71             is => 'ro',
72             builder => '_open_filehandle',
73             init_arg => undef,
74             lazy => 1,
75             );
76              
77             has '_stored_record_header' => (
78             is => 'rw',
79             clearer => '_clear_stored_record_header',
80             predicate => '_has_stored_record_header',
81             init_arg => undef,
82             );
83              
84             has '_stored_record_sequence_parts' => (
85             traits => ['Array'],
86             is => 'rw',
87             isa => 'ArrayRef[Str]',
88             default => sub { [] },
89             handles => {
90             _all_record_sequence_parts => 'elements',
91             _add_record_sequence_part => 'push',
92             _join_record_sequence_parts => 'join',
93             _clear_record_sequence_parts => 'clear',
94             },
95             );
96              
97             has '_eof' => (
98             is => 'rw',
99             predicate => '_reached_eof',
100             init_arg => undef
101             );
102              
103              
104             #######################################################################
105             ######################## Interface Methods ########################
106             #######################################################################
107             sub next_record {
108 24     24 0 736 my ($self) = @_;
109              
110 24 100       829 return undef if ($self->_reached_eof);
111              
112 22         579 while (my $line = $self->_filehandle->getline) {
113 78         2383 chomp $line;
114 78 100       140 if (_line_looks_like_record_header($line)) {
    100          
115 23 100       799 if ($self->_has_stored_record_header) {
116 20         44 my $record = $self->_create_record;
117 20         528 $self->_stored_record_header($line);
118 20         144 return $record;
119             }
120             else {
121 3         91 $self->_stored_record_header($line);
122             }
123             }
124             elsif (_line_looks_like_sequence($line)) {
125 44         1743 $self->_add_record_sequence_part($line);
126             }
127             }
128 2         99 $self->_eof(1);
129 2         5 return $self->_create_record;
130             }
131              
132             #######################################################################
133             ######################### Private methods ##########################
134             #######################################################################
135             sub _open_filehandle {
136 3     3   3 my ($self) = @_;
137              
138 3         4 my $read_mode;
139             my $HANDLE;
140 3 50       80 if (!defined $self->file) {
    50          
141 0         0 open ($HANDLE, '<-', $self->file);
142             }
143             elsif ($self->file =~ /\.gz$/) {
144 3 50       70 die 'Cannot open file ' . $self->file . "\n" if ! -e $self->file;
145 3         79 open($HANDLE, 'gzip -dc ' . $self->file . ' |');
146             }
147             else {
148 0         0 open ($HANDLE, '<', $self->file);
149             }
150              
151 3         13170 return $HANDLE;
152             }
153              
154             sub _increment_records_read_count {
155 22     22   26 my ($self) = @_;
156 22         608 $self->records_read_count($self->records_read_count+1);
157             }
158              
159             sub _create_record {
160 22     22   34 my ($self) = @_;
161              
162 22         594 my $record = GenOO::Data::File::FASTA::Record->new(
163             header => $self->_stored_record_header,
164             sequence => $self->_join_record_sequence_parts(''),
165             );
166 22         785 $self->_clear_stored_record_header;
167 22         882 $self->_clear_record_sequence_parts;
168 22         41 $self->_increment_records_read_count;
169              
170 22         35 return $record;
171             }
172              
173              
174             #######################################################################
175             ####################### Private subroutines ########################
176             #######################################################################
177             sub _line_looks_like_record_header {
178 133 100   133   929 return ($_[0] =~ /^>/) ? 1 : 0;
179             }
180              
181             sub _line_looks_like_sequence {
182 55 100 66 55   82 return ((!_line_looks_like_record_header($_[0])) and ($_[0] =~ /\S/)) ? 1 : 0;
183             }
184              
185              
186             #######################################################################
187             ############################ Finalize #############################
188             #######################################################################
189             __PACKAGE__->meta->make_immutable;
190              
191             1;