File Coverage

Bio/Matrix/PSM/IO/transfac.pm
Criterion Covered Total %
statement 100 135 74.0
branch 24 46 52.1
condition 6 9 66.6
subroutine 12 13 92.3
pod 2 2 100.0
total 144 205 70.2


line stmt bran cond sub pod time code
1             #---------------------------------------------------------
2              
3             =head1 NAME
4              
5             Bio::Matrix::PSM::IO::transfac - PSM transfac parser
6              
7             =head1 SYNOPSIS
8              
9             See Bio::Matrix::PSM::IO for documentation
10              
11             =head1 DESCRIPTION
12              
13             #
14              
15             =head1 FEEDBACK
16              
17             =head2 Mailing Lists
18              
19             User feedback is an integral part of the evolution of this and other
20             Bioperl modules. Send your comments and suggestions preferably to one
21             of the Bioperl mailing lists. Your participation is much appreciated.
22              
23             bioperl-l@bioperl.org - General discussion
24             http://bioperl.org/wiki/Mailing_lists - About the mailing lists
25              
26             =head2 Support
27              
28             Please direct usage questions or support issues to the mailing list:
29              
30             I
31              
32             rather than to the module maintainer directly. Many experienced and
33             reponsive experts will be able look at the problem and quickly
34             address it. Please include a thorough description of the problem
35             with code and data examples if at all possible.
36              
37             =head2 Reporting Bugs
38              
39             Report bugs to the Bioperl bug tracking system to help us keep track
40             the bugs and their resolution. Bug reports can be submitted via the
41             web:
42              
43             https://github.com/bioperl/bioperl-live/issues
44              
45             =head1 AUTHOR - Stefan Kirov
46              
47             Email skirov@utk.edu
48              
49             =head1 APPENDIX
50              
51             =cut
52              
53              
54             # Let the code begin...
55             package Bio::Matrix::PSM::IO::transfac;
56 1     1   5 use Bio::Matrix::PSM::Psm;
  1         2  
  1         24  
57 1     1   4 use Bio::Root::Root;
  1         1  
  1         19  
58 1     1   293 use Bio::Annotation::Reference;
  1         2  
  1         23  
59 1     1   329 use Bio::Annotation::Comment;
  1         2  
  1         21  
60 1     1   5 use Bio::Annotation::DBLink;
  1         1  
  1         18  
61 1     1   3 use strict;
  1         1  
  1         18  
62              
63 1     1   3 use base qw(Bio::Matrix::PSM::PsmHeader Bio::Matrix::PSM::IO);
  1         2  
  1         1015  
64              
65             =head2 new
66              
67             Title : new
68             Usage : my $psmIO = Bio::Matrix::PSM::IO->new(-format=>'transfac',
69             -file=>$file);
70             Function: Associates a file with the appropriate parser
71             Throws :
72             Example :
73             Args :
74             Returns : "Bio::Matrix::PSM::$format"->new(@args);
75              
76             =cut
77              
78             sub new {
79 1     1 1 5 my ($class,@args)=@_;
80 1         1 my $line;
81 1         7 my $self = $class->SUPER::new(@args);
82 1         5 my ($file)=$self->_rearrange(['FILE'], @args);
83 1 50       6 $self->_initialize_io(@args) || warn "Did you intend to use STDIN?"; #Read only for now
84             #Remove header
85 1   66     2 do {
86 3         9 $line=$self->_readline;
87 3         5 chomp $line;
88 3 100       9 push @{$self->{unstructured}},$line if (length($line)>2); } until ($line =~ m{^//}) || (!defined($line)); #Unstructured header
  1         7  
89 1         5 $self->_initialize;
90 1         9 return $self;
91             }
92              
93              
94             =head2 next_psm
95              
96             Title : next_psm
97             Usage : my $psm=$psmIO->next_psm();
98             Function: Reads the next PSM from the input file, associated with this object
99             Throws : Upon finding a line, defining the matrix, where one or more positions
100             are not defined, see _make_matrix
101             Returns : Bio::Matrix::PSM::Psm object
102             Args : none
103              
104             =cut
105              
106             sub next_psm {
107 1     1 1 2 my $self=shift;
108 1         1 my $line;
109 1 50       4 return if ($self->{end});
110 1         1 my (@a,@c,@g,@t, $id, $tr1, @refs,$accn, $bf, $sites);
111 1         2 my $i=0;
112 1         3 while (defined( $line=$self->_readline)) {
113 28         29 chomp($line);
114 28 100       57 if ($line=~/^\d{2}/) { #Begining of the frequency data
115 12         15 ($a[$i],$c[$i],$g[$i],$t[$i])=_parse_matrix($line);
116 12         13 $i++;
117             }
118 28 100       43 ($tr1,$accn)=split(/\s{2}/,$line) if ($line=~/^AC\s/);
119 28 100       36 ($tr1,$bf)=split(/\s{2}/,$line) if ($line=~/^BF\s/);
120 28 100       39 ($tr1,$id)=split(/\s{2}/,$line) if ($line=~/^ID\s/);
121 28 100 100     71 last if (($line=~/^XX/) && ($i>0));
122             }
123 1 50 33     8 if (!(defined($id) && defined($accn))) {
124 0         0 $self->{end}=1;
125 0         0 return;
126             }
127 1         3 while (defined( $line=$self->_readline)) { #How many sites?
128 5 100       9 if ($line=~/^BA\s/) {
129 1         4 my ($tr1,$ba)=split(/\s{2}/,$line);
130 1         3 ($sites)=split(/\s/,$ba);
131             }
132 5 50       6 if ($line=~/^RN/) { #Adding a reference as Bio::Annotation object (self)
133             # not interested in RN line itself, since has only transfac-specific
134             # reference id? - no push back of line
135 0         0 my $ref=_parse_ref($self);
136 0         0 push @refs,$ref
137             }
138 5 100       11 last if ($line=~m{^//});
139             }
140             # We have the frequencies, let's create a SiteMatrix object
141 1         2 my %matrix = &_make_matrix($self,\@a,\@c,\@g,\@t,$id, $accn);
142 1 50       3 $matrix{-sites}=$sites if ($sites);
143 1         2 $matrix{-width}=@a;
144 1         9 my $psm=Bio::Matrix::PSM::Psm->new(%matrix);
145 1         3 foreach my $ref (@refs) { $psm->add_Annotation('reference',$ref); }
  0         0  
146 1         6 return $psm;
147             }
148              
149             =head2 _parseMatrix
150              
151             Title : _parseMatrix
152             Usage :
153             Function: Parses a line
154             Throws :
155             Example : Internal stuff
156             Returns : array (frequencies for A,C,G,T in this order).
157             Args : string
158              
159             =cut
160              
161             sub _parse_matrix {
162 12     12   12 my $line=shift;
163 12         39 $line=~s/\s+/,/g;
164 12         34 my ($tr,$a,$c,$g,$t)=split(/,/,$line);
165 12         37 return $a,$c,$g,$t;
166             }
167              
168              
169             =head2 _make_matrix
170              
171             Title : _make_matrix
172             Usage :
173             Function:
174             Throws : If a position is undefined, for example if you have line like this
175             in the file you are parsing: 08 4,7,,9
176             Example : Internal stuff
177             Returns :
178             Args :
179              
180             =cut
181              
182             sub _make_matrix {
183 1     1   2 my ($a, $c, $g, $t, @fa, @fc,@fg, @ft, @a,@c,@g,@t);
184 1         2 my $ave=0;
185 1         2 my ($self,$cA,$cC,$cG,$cT, $id, $accn)= @_;
186              
187 1         1 for (my $i=0; $i < @{$cA};$i++) {
  13         21  
188             #No value can be undefined -throw an exception, since setting to 0 probably would be wrong
189             #If this happens it would indicate most probably that the file, being parsed is in a different format
190 12 50       13 map { $self->throw('Parsing error, a position is not defined') unless defined(${$_}[$i]) } ($cA, $cG, $cC, $cT);
  48         42  
  48         81  
191            
192 12 50       12 if ( (${$cA}[$i] + ${$cC}[$i] +
  12         12  
  12         15  
193 12         13 ${$cG}[$i] + ${$cT}[$i] ) ==0 ) {
  12         17  
194 0         0 push @a,$ave;
195 0         0 push @c,$ave;
196 0         0 push @g,$ave;
197 0         0 push @t,$ave;
198             }
199             else {
200 12         12 push @a,${$cA}[$i];
  12         14  
201 12         13 push @c,${$cC}[$i];
  12         16  
202 12         13 push @g,${$cG}[$i];
  12         13  
203 12         11 push @t,${$cT}[$i];
  12         17  
204 12         12 $ave = ((${$cA}[$i]+${$cC}[$i]+
  12         12  
205 12         13 ${$cG}[$i]+${$cT}[$i]) / 4 +$ave)/2;
  12         10  
  12         18  
206             }
207             }
208              
209 1         2 for (my $i=0; $i<@a;$i++) {
210 12         15 my $zero=($a[$i]+$c[$i]+$g[$i]+$t[$i]);
211 12 50       15 next if ($zero==0);
212 12         14 push @fa, $a[$i];
213 12         14 push @fc, $c[$i];
214 12         16 push @fg, $g[$i];
215 12         20 push @ft, $t[$i];
216             }
217 1         10 return (-pA=>\@fa,-pC=>\@fc,-pG=>\@fg,-pT=>\@ft, -id=>$id, -accession_number=>$accn)
218             }
219              
220             sub _parse_ref {
221 0     0   0 my $self=shift;
222 0         0 my ($authors,$title,$loc,@refs,$tr,$db,$dbid);
223 0         0 while (my $refline=$self->_readline) { #Poorely designed, should go through an array with fields
224 0         0 chomp $refline;
225 0         0 my ($field,$arg)=split(/\s+/,$refline,2);
226 0 0       0 last if ($field=~/XX/);
227 0         0 $field.=' ';
228             REF: {
229 0 0       0 if ($field=~/RX/) { #DB Reference
  0         0  
230 0         0 $refline=~s/[;\.]//g;
231 0         0 ($tr, $db, $dbid)=split(/\s+/,$refline);
232 0         0 last REF;
233             }
234 0 0       0 if ($field=~/RT/) { #Title
235 0         0 $title .= $arg;
236 0         0 last REF;
237             }
238 0 0       0 if ($field=~/RA/) { #Author
239 0         0 $authors .= $arg;
240 0         0 last REF;
241             }
242 0 0       0 if ($field=~/RL/) { #Journal
243 0         0 $loc .= $arg;
244 0         0 last REF;
245             }
246             }
247             }
248 0         0 my $reference=Bio::Annotation::Reference->new(-authors=>$authors, -title=>$title,
249             -location=>$loc);
250 0 0       0 if ($db eq 'MEDLINE') {
    0          
251             # does it ever equal medline?
252 0         0 $reference->medline($dbid);
253             }
254             elsif ($dbid) {
255 0         0 $reference->pubmed($dbid);
256             }
257 0         0 return $reference;
258             }
259              
260             sub DESTROY {
261 1     1   3 my $self=shift;
262 1         17 $self->close;
263             }
264              
265             1;
266