File Coverage

Bio/Tools/FootPrinter.pm
Criterion Covered Total %
statement 90 93 96.7
branch 22 30 73.3
condition 4 9 44.4
subroutine 10 10 100.0
pod 0 2 0.0
total 126 144 87.5


line stmt bran cond sub pod time code
1             # BioPerl module for Bio::Tools::FootPrinter
2             #
3             # Please direct questions and support issues to
4             #
5             # Cared for by Shawn Hoon
6             #
7             # Copyright Shawn Hoon
8             #
9             # You may distribute this module under the same terms as perl itself
10              
11             # POD documentation - main docs before the code
12              
13             =head1 NAME
14              
15             Bio::Tools::FootPrinter - write sequence features in FootPrinter format
16              
17             =head1 SYNOPSIS
18              
19             use Bio::Tools::FootPrinter;
20              
21             my $tool = Bio::Tools::FootPrinter->new(-file=>"footprinter.out");
22              
23             while (my $result = $tool->next_feature){
24             foreach my $feat($result->sub_SeqFeature){
25             print $result->seq_id."\t".$feat->start."\t".$feat->end."\t".$feat->seq->seq."\n";
26             }
27             }
28              
29             =head1 DESCRIPTION
30              
31             This module writes sequence features in FootPrinter format.
32             See L for more details.
33              
34             =head1 FEEDBACK
35              
36             =head2 Mailing Lists
37              
38             User feedback is an integral part of the evolution of this and other
39             Bioperl modules. Send your comments and suggestions preferably to
40             the Bioperl mailing list. Your participation is much appreciated.
41              
42             bioperl-l@bioperl.org - General discussion
43             http://bioperl.org/wiki/Mailing_lists - About the mailing lists
44              
45             =head2 Support
46              
47             Please direct usage questions or support issues to the mailing list:
48              
49             I
50              
51             rather than to the module maintainer directly. Many experienced and
52             reponsive experts will be able look at the problem and quickly
53             address it. Please include a thorough description of the problem
54             with code and data examples if at all possible.
55              
56             =head2 Reporting Bugs
57              
58             Report bugs to the Bioperl bug tracking system to help us keep track
59             of the bugs and their resolution. Bug reports can be submitted via the
60             web:
61              
62             https://github.com/bioperl/bioperl-live/issues
63              
64             =head1 AUTHOR - Shawn Hoon
65              
66             Email shawnh@fugu-sg.org
67              
68             =head1 APPENDIX
69              
70             The rest of the documentation details each of the object methods.
71             Internal methods are usually preceded with a _
72              
73             =cut
74              
75              
76             # Let the code begin...
77              
78              
79             package Bio::Tools::FootPrinter;
80 1     1   411 use strict;
  1         1  
  1         23  
81              
82 1     1   355 use Bio::SeqFeature::Generic;
  1         1  
  1         25  
83 1     1   5 use Bio::PrimarySeq;
  1         1  
  1         17  
84              
85 1     1   3 use base qw(Bio::Root::Root Bio::Root::IO);
  1         1  
  1         632  
86              
87             =head2 new
88              
89             Title : new
90             Usage : my $obj = Bio::Tools::FootPrinter->new();
91             Function: Builds a new Bio::Tools::FootPrinter object
92             Returns : Bio::Tools::FootPrinter
93             Args : -fh/-file => $val, # for initing input, see Bio::Root::IO
94              
95             =cut
96              
97             sub new {
98 1     1 0 13 my($class,@args) = @_;
99              
100 1         10 my $self = $class->SUPER::new(@args);
101 1         7 $self->_initialize_io(@args);
102              
103 1         2 return $self;
104             }
105              
106             =head2 next_feature
107              
108             Title : next_feature
109             Usage : my $r = $footprint->next_feature
110             Function: Get the next feature from parser data
111             Returns : L
112             Args : none
113              
114             =cut
115              
116             sub next_feature{
117 7     7 0 15 my ($self) = @_;
118 7 100       10 $self->_parse_predictions() unless $self->_predictions_parsed();
119 7         8 return shift @{$self->{'_feature'}};
  7         13  
120              
121             }
122              
123             =head2 _add_feature
124              
125             Title : _add_feature
126             Usage : $footprint->_add_feature($feat)
127             Function: Add feature to array
128             Returns : none
129             Args : none
130              
131             =cut
132              
133             sub _add_feature {
134 6     6   7 my ($self,$feat) = @_;
135 6 50       12 if($feat){
136 6         3 push @{$self->{'_feature'}},$feat;
  6         14  
137             }
138             }
139              
140             =head2 _parse_predictions
141              
142             Title : _parse_predictions
143             Usage : my $r = $footprint->_parse_predictions
144             Function: do the parsing
145             Returns : none
146             Args : none
147              
148             =cut
149              
150             sub _parse_predictions {
151 1     1   2 my ($self) = @_;
152 1         2 $/="";
153 1         1 my ($seq,$second,$third,$name);
154 1         7 while ($_ = $self->_readline) {
155 59         49 chomp;
156 59         103 my @array = split("\n",$_);
157 59 50       77 if ($#array == 5) {
158             # get rid of header
159 0         0 shift(@array); shift(@array);
  0         0  
160             }
161 59 100       67 if($#array == 3){
162 6 100       9 if($name){
163 5         11 $name=~s/>//;
164 5         11 my $feat = $self->_parse($name,$seq,$second,$third);
165 5         9 $self->_add_feature($feat);
166             }
167 6         8 $name = shift @array;
168 6         7 $seq = $array[0];
169 6         6 $second = $array[1];
170 6         5 $third = $array[2];
171 6         19 next;
172             }
173 53         55 $seq .= $array[0];
174 53         91 $third .= $array[2];
175             }
176            
177 1 50       4 $seq || return;
178            
179 1         3 $name=~s/>//;
180 1         2 my $feat = $self->_parse($name,$seq,$second,$third);
181 1         4 $self->_add_feature($feat);
182              
183 1         5 $self->_predictions_parsed(1);
184             }
185              
186             =head2 _predictions_parsed
187              
188             Title : _predictions_parsed
189             Usage : $footprint->_predictions_parsed(1)
190             Function: Get/Set for whether predictions parsed
191             Returns : 1/0
192             Args : none
193              
194             =cut
195              
196             sub _predictions_parsed {
197 8     8   10 my ($self,$val) = @_;
198 8 100       12 if($val){
199 1         1 $self->{'_predictions_parsed'} = $val;
200             }
201 8         18 return $self->{'_predictions_parsed'};
202             }
203              
204              
205             =head2 _parse
206              
207             Title : _parse
208             Usage : $footprint->_parse($name,$seq,$pattern)
209             Function: do the actual parsing
210             Returns : L
211             Args : none
212              
213             =cut
214              
215             sub _parse {
216 6     6   7 my ($self,$name,$seq,$score,$pattern) = @_;
217 6         311 my @char = split('',$pattern);
218 6         47 my @score = split('',$score);
219              
220 6         5 my ($prev,$word,@words,@word_scores,$word_score);
221              
222 6         7 my $i = 0;
223 6         11 for my $c ( @char ) {
224 4702 100       5132 if( ! $word) {
    100          
225 6         9 $word .= $c;
226 6         6 $prev = $c;
227 6 50 33     35 defined $score[$i] &&
228             ($score[$i] =~ /\d/) && ($word_score += $score[$i]);
229             } elsif ($c eq $prev){
230 4677         2555 $word .=$c;
231 4677         2719 $prev = $c;
232 4677 50 66     6395 defined $score[$i] &&
233             ($score[$i] =~ /\d/) && ($word_score += $score[$i]);
234             } else {
235             # remove words with only \s
236 19         48 $word=~s/\s+//g;
237 19 100       30 if ($word ne ''){
238 12         19 push @words, $word;
239 12         15 push @word_scores, ($word_score/length($word));
240             }
241 19         15 $word =$c;
242 19         10 $prev = $c;
243 19         18 $word_score = 0;
244 19 50 33     30 defined $score[$i] &&
245             ($score[$i] =~ /\d/) && ($word_score += $score[$i]);
246             }
247 4702         3095 $i++;
248             }
249 6         26 $word =~s/\s+//g;
250 6 50       14 if( length($word) ){
251 0         0 push @words, $word;
252             }
253 6         4 my $last;
254 6         30 my $feat = Bio::SeqFeature::Generic->new(-seq_id=>$name);
255 6         7 my $offset = $i = 0;
256 6         4 my $count = 1;
257 6         8 for my $w (@words){
258 12 50       18 if(length($w) ) {
259 12         19 my $index = index($pattern,$w,$offset);
260 12         10 $offset = $index + length($w);
261 12         55 my $subfeat = Bio::SeqFeature::Generic->new
262             ( -seq_id =>"$name-motif".$count++,
263             -start => $index+1,
264             -end => $index+length($w),
265             -source =>"FootPrinter",
266             -score => $word_scores[$i]
267             );
268             # ugh - not sure the sub_SeqFeature situation will
269             # be around forever- things should probably be
270             # grouped by a 'group' tag instead ala GFF3
271             # perhaps when Lincoln's API changes are
272             # made to SeqFeatures this will get changed
273 12         26 $feat->add_sub_SeqFeature($subfeat,'EXPAND');
274             }
275 12         14 $i++;
276             }
277 6         25 my $priseq = Bio::PrimarySeq->new(-id=>$name,-seq=>$seq);
278 6         14 $feat->attach_seq($priseq);
279 6         192 return $feat;
280              
281             }
282              
283             1;