File Coverage

blib/lib/Bio/GFF3/Transform/FromFasta.pm
Criterion Covered Total %
statement 53 53 100.0
branch 12 20 60.0
condition 7 13 53.8
subroutine 11 11 100.0
pod 1 1 100.0
total 84 98 85.7


line stmt bran cond sub pod time code
1             package Bio::GFF3::Transform::FromFasta;
2             BEGIN {
3 1     1   74244 $Bio::GFF3::Transform::FromFasta::AUTHORITY = 'cpan:RBUELS';
4             }
5             {
6             $Bio::GFF3::Transform::FromFasta::VERSION = '2.0';
7             }
8             # ABSTRACT: make gff3 for the sequences in a fasta file
9              
10 1     1   9 use strict;
  1         1  
  1         29  
11 1     1   5 use warnings;
  1         2  
  1         23  
12 1     1   4 use Carp;
  1         2  
  1         81  
13 1     1   7 use Scalar::Util 'blessed';
  1         1  
  1         47  
14              
15 1     1   12 use base 'Exporter';
  1         2  
  1         127  
16             our @EXPORT_OK = ( 'gff3_from_fasta' );
17              
18 1     1   510 use Bio::GFF3::LowLevel 'gff3_format_feature';
  1         3  
  1         676  
19              
20              
21             sub gff3_from_fasta {
22 4     4 1 10239 my %args = @_;
23 4 50       22 $args{out} or croak 'must provide "out" arg';
24              
25 4 50       17 $args{in} or croak 'must provide "in" arg';
26 4 50       26 $args{in} = [ $args{in} ] unless ref $args{in} eq 'ARRAY';
27 4 50       14 $args{type} or croak( 'must provide "type" arg');
28              
29 4         41 my $out_fh = _to_filehandle($args{out},'>');
30              
31 4         13 my @fhs =
32             map _to_filehandle($_),
33 4         8 @{ $args{in} };
34              
35 4         17 print $out_fh "##gff-version 3\n";
36 4         90 for my $fh ( @fhs ) {
37             _for_fasta( $fh, sub {
38 8     8   14 my ( $ident, $desc, $seq ) = @_;
39              
40 8 100 50     119 print $out_fh gff3_format_feature({
41             seq_id => $$ident,
42             source => $args{source} || 'fasta',
43             type => $args{type},
44             start => 1,
45             end => length($$seq),
46             strand => '+',
47             attributes => {
48             Name => [ $$ident ],
49             ( $$desc ? (Note => [ $$desc ]) : () ),
50             },
51             });
52 4         30 });
53             }
54              
55 4 50       161 if( $args{fasta_section} ) {
56 4         31 seek( $_, 0, 0 ) for @fhs;
57 4         44 print $out_fh "##FASTA\n";
58 4         63 local $_;
59 4         8 for my $fh (@fhs) {
60 4         33 while( <$fh> ) {
61 60         1433 chomp;
62 60 100       183 s/\s//g unless /^>/;
63 60         150 print $out_fh $_,"\n";
64             }
65             }
66             }
67             }
68              
69             sub _for_fasta {
70 4     4   5 my ( $fh, $cb ) = @_;
71              
72 4         15 local $/ = "\n>";
73 4         46 while( my $seq = <$fh> ) {
74 8         249 $seq =~ s/\s*>?\s*//;
75 8 50       43 $seq =~ s/^(\S+) *(.*)//
76             or croak 'error parsing fasta';
77 8         30 my ( $ident, $desc ) = ( $1, $2 );
78 8         84 $seq =~ s/\s//g;
79 8         22 $cb->( \$ident, \$desc, \$seq );
80             }
81              
82             }
83              
84             sub _to_filehandle {
85 8     8   15 my ( $thing, $mode ) = @_;
86              
87 8 50 66     132 return $thing if
      33        
      66        
88             $thing
89             && ref $thing
90             && ( ref $thing eq 'GLOB'
91             || blessed $thing && $thing->can('print')
92             );
93              
94 2 50 50     89 open( my $f, ($mode || '<'), $thing) or confess "$! opening $thing";
95 2         10 return $f;
96             }
97              
98             1;
99              
100             __END__