Bio::DB::Universal: move into its own distribution
[bioperl-live.git] / Bio / Tools / FootPrinter.pm
blobdedb71920859736def1038f109c32b4b1e6a00c2
1 # BioPerl module for Bio::Tools::FootPrinter
3 # Please direct questions and support issues to <bioperl-l@bioperl.org>
5 # Cared for by Shawn Hoon <shawnh@fugu-sg.org>
7 # Copyright Shawn Hoon
9 # You may distribute this module under the same terms as perl itself
11 # POD documentation - main docs before the code
13 =head1 NAME
15 Bio::Tools::FootPrinter - write sequence features in FootPrinter format
17 =head1 SYNOPSIS
19 use Bio::Tools::FootPrinter;
21 my $tool = Bio::Tools::FootPrinter->new(-file=>"footprinter.out");
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";
29 =head1 DESCRIPTION
31 This module writes sequence features in FootPrinter format.
32 See L<http://bio.cs.washington.edu/software.html> for more details.
34 =head1 FEEDBACK
36 =head2 Mailing Lists
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.
42 bioperl-l@bioperl.org - General discussion
43 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
45 =head2 Support
47 Please direct usage questions or support issues to the mailing list:
49 I<bioperl-l@bioperl.org>
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.
56 =head2 Reporting Bugs
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:
62 https://github.com/bioperl/bioperl-live/issues
64 =head1 AUTHOR - Shawn Hoon
66 Email shawnh@fugu-sg.org
68 =head1 APPENDIX
70 The rest of the documentation details each of the object methods.
71 Internal methods are usually preceded with a _
73 =cut
76 # Let the code begin...
79 package Bio::Tools::FootPrinter;
80 use strict;
82 use Bio::SeqFeature::Generic;
83 use Bio::PrimarySeq;
85 use base qw(Bio::Root::Root Bio::Root::IO);
87 =head2 new
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
95 =cut
97 sub new {
98 my($class,@args) = @_;
100 my $self = $class->SUPER::new(@args);
101 $self->_initialize_io(@args);
103 return $self;
106 =head2 next_feature
108 Title : next_feature
109 Usage : my $r = $footprint->next_feature
110 Function: Get the next feature from parser data
111 Returns : L<Bio::SeqFeature::Generic>
112 Args : none
114 =cut
116 sub next_feature{
117 my ($self) = @_;
118 $self->_parse_predictions() unless $self->_predictions_parsed();
119 return shift @{$self->{'_feature'}};
123 =head2 _add_feature
125 Title : _add_feature
126 Usage : $footprint->_add_feature($feat)
127 Function: Add feature to array
128 Returns : none
129 Args : none
131 =cut
133 sub _add_feature {
134 my ($self,$feat) = @_;
135 if($feat){
136 push @{$self->{'_feature'}},$feat;
140 =head2 _parse_predictions
142 Title : _parse_predictions
143 Usage : my $r = $footprint->_parse_predictions
144 Function: do the parsing
145 Returns : none
146 Args : none
148 =cut
150 sub _parse_predictions {
151 my ($self) = @_;
152 $/="";
153 my ($seq,$second,$third,$name);
154 while ($_ = $self->_readline) {
155 chomp;
156 my @array = split("\n",$_);
157 if ($#array == 5) {
158 # get rid of header
159 shift(@array); shift(@array);
161 if($#array == 3){
162 if($name){
163 $name=~s/>//;
164 my $feat = $self->_parse($name,$seq,$second,$third);
165 $self->_add_feature($feat);
167 $name = shift @array;
168 $seq = $array[0];
169 $second = $array[1];
170 $third = $array[2];
171 next;
173 $seq .= $array[0];
174 $third .= $array[2];
177 $seq || return;
179 $name=~s/>//;
180 my $feat = $self->_parse($name,$seq,$second,$third);
181 $self->_add_feature($feat);
183 $self->_predictions_parsed(1);
186 =head2 _predictions_parsed
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
194 =cut
196 sub _predictions_parsed {
197 my ($self,$val) = @_;
198 if($val){
199 $self->{'_predictions_parsed'} = $val;
201 return $self->{'_predictions_parsed'};
205 =head2 _parse
207 Title : _parse
208 Usage : $footprint->_parse($name,$seq,$pattern)
209 Function: do the actual parsing
210 Returns : L<Bio::SeqFeature::Generic>
211 Args : none
213 =cut
215 sub _parse {
216 my ($self,$name,$seq,$score,$pattern) = @_;
217 my @char = split('',$pattern);
218 my @score = split('',$score);
220 my ($prev,$word,@words,@word_scores,$word_score);
222 my $i = 0;
223 for my $c ( @char ) {
224 if( ! $word) {
225 $word .= $c;
226 $prev = $c;
227 defined $score[$i] &&
228 ($score[$i] =~ /\d/) && ($word_score += $score[$i]);
229 } elsif ($c eq $prev){
230 $word .=$c;
231 $prev = $c;
232 defined $score[$i] &&
233 ($score[$i] =~ /\d/) && ($word_score += $score[$i]);
234 } else {
235 # remove words with only \s
236 $word=~s/\s+//g;
237 if ($word ne ''){
238 push @words, $word;
239 push @word_scores, ($word_score/length($word));
241 $word =$c;
242 $prev = $c;
243 $word_score = 0;
244 defined $score[$i] &&
245 ($score[$i] =~ /\d/) && ($word_score += $score[$i]);
247 $i++;
249 $word =~s/\s+//g;
250 if( length($word) ){
251 push @words, $word;
253 my $last;
254 my $feat = Bio::SeqFeature::Generic->new(-seq_id=>$name);
255 my $offset = $i = 0;
256 my $count = 1;
257 for my $w (@words){
258 if(length($w) ) {
259 my $index = index($pattern,$w,$offset);
260 $offset = $index + length($w);
261 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]
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 $feat->add_sub_SeqFeature($subfeat,'EXPAND');
275 $i++;
277 my $priseq = Bio::PrimarySeq->new(-id=>$name,-seq=>$seq);
278 $feat->attach_seq($priseq);
279 return $feat;