root/lib/Fasta.pm

Revision 278, 9.6 kB (checked in by cholt, 3 weeks ago)

fix fasta parsing

Line 
1 #-------------------------------------------------------------------------------
2 #------                            Fasta                               ---------
3 #-------------------------------------------------------------------------------
4 package Fasta;
5 use strict;
6 use vars qw(@ISA @EXPORT $VERSION);
7 use Exporter;
8 use PostData;
9 use FileHandle;
10 use URI::Escape;
11
12 @ISA = qw(
13           );
14
15 #-------------------------------------------------------------------------------
16 #------------------------------- Methods ---------------------------------------
17 #-------------------------------------------------------------------------------
18 sub new {
19         my $class = shift;
20         my $fasta = shift;
21
22         my $self = {};
23
24         bless $self, $class;
25
26         $self->fasta($fasta);
27
28         return $self;
29 }
30 #-------------------------------------------------------------------------------
31 sub identifier {
32         my $self = shift;
33         my $id   = shift;
34
35         if (defined($id)){
36                 $self->{identifier} = $id;
37         }
38         elsif (defined($self->{identifier})){
39                 return $self->{identifier};
40         }
41         else {
42                 my ($id) = $self->def() =~ /^>(\S+)/;
43                 $self->{identifier} = $id;
44                 return $self->{identifier};
45         }
46 }
47 #-------------------------------------------------------------------------------
48 sub fasta {
49         my $self  = shift;
50         my $fasta = shift;
51
52         if (defined($fasta)){
53                 $self->{fasta} = $fasta;
54         }
55         else {
56                 return $self->{fasta};
57         }
58 }
59 #-------------------------------------------------------------------------------
60 sub seq {
61         my $self = shift;
62         my $seq  = shift;
63
64         if  (defined($seq) && $seq eq 'revComp' && !defined($self->{seq})){
65                 my @a = split(/\n/, $self->fasta());
66                 shift(@a);
67                 $self->{seq} = join('', @a);;
68                 return revComp($self->{seq});
69         }
70         if (defined($seq) && $seq eq 'revComp'){
71                 return revComp($self->{seq});
72         }
73         elsif (defined($seq)){
74                 $self->{seq} = $seq;
75         }
76         elsif (defined($self->{seq})){
77                 return $self->{seq};
78         }
79         else {
80                 my @a = split(/\n/, $self->fasta());
81                 shift(@a);
82                 $self->{seq} = join('', @a);;
83                 return $self->{seq};
84         }
85 }
86 #-------------------------------------------------------------------------------
87 sub def {
88         my $self = shift;
89         my $def  = shift;
90
91         if (defined($def)){
92                 $self->{def} = $def;
93         }
94         elsif (defined($self->{def})){
95                 return $self->{def};
96         }
97         else {
98                 my @a = split(/\n/, $self->fasta());
99                 $self->{def} = shift(@a);
100                 return $self->{def};
101         }
102 }
103 #-------------------------------------------------------------------------------
104 #------------------------------- SUBS ------------------------------------------
105 #-------------------------------------------------------------------------------
106 sub getWantedFromMulti {
107         my $multiFasta = shift;
108         my $wanted     = shift;
109
110         local $/ = "\n>";
111
112         my $fh = new FileHandle;
113            $fh->open("$multiFasta");
114
115         my @fastas;
116         while(my $line = <$fh>){
117                 $line =~ s/>//;
118                 $line = ">".$line;
119                 if (!defined($wanted) || $line =~ /$wanted/){
120                         push(@fastas, $line);
121                 }
122         }
123         local $/ = "\n";
124         $fh->close;
125
126         return \@fastas;
127 }
128 #-----------------------------------------------------------------------------
129 sub getDef {
130         my $fasta = shift;
131
132         #always work with references
133         $fasta = $$fasta while(ref($fasta) eq 'REF');
134         my $fasta_ref = (ref($fasta) eq '') ? \$fasta : $fasta;
135
136         my @fasta = split(/\n/, $$fasta_ref);
137         while(my $l = shift(@fasta)){
138                 chomp($l);
139                 return $l if $l =~ /^>/;
140         }
141 }
142 #-----------------------------------------------------------------------------
143 sub getSeqID {
144         my $fasta = shift;
145
146         #always work with references
147         $fasta = $$fasta while(ref($fasta) eq 'REF');
148         my $fasta_ref = (ref($fasta) eq '') ? \$fasta : $fasta;
149
150         my $def = Fasta::getDef($fasta_ref);
151         my $seq_id = def2SeqID($def);
152
153         return $seq_id;
154 }
155 #-----------------------------------------------------------------------------
156 sub def2SeqID {
157         my $def = shift;
158
159         my ($seq_id)  = $def =~ /^>(\S+)/;
160
161         return $seq_id;
162 }
163 #-----------------------------------------------------------------------------
164 sub getSafeID {
165         my $fasta = shift;
166
167         #always work with references
168         $fasta = $$fasta while(ref($fasta) eq 'REF');
169         my $fasta_ref = (ref($fasta) eq '') ? \$fasta : $fasta;
170
171         my $seq_id = getSeqID($fasta_ref);
172         my $safe_id = SeqID2SafeID($seq_id);
173
174         return $safe_id;
175 }
176 #-----------------------------------------------------------------------------
177 sub seqID2SafeID {
178     my $seq_id = shift;
179    
180     my $safe_id = uri_escape($seq_id, 
181                              '\*\?\|\\\/\'\"\{\}\<\>\;\,\^\(\)\$\~\:'
182                              );
183    
184     return $safe_id;
185 }
186 #-----------------------------------------------------------------------------
187 sub safeID2SeqID {
188     my $seq_id = shift;
189
190     my $safe_id = uri_unescape($seq_id);
191    
192     return $safe_id;
193 }
194 #-------------------------------------------------------------------------------
195 sub getSeq {
196     my $fasta = shift;
197
198     return ${getSeqRef(\$fasta)};
199 }
200 #-------------------------------------------------------------------------------
201 sub getSeqRef {
202     my $fasta = shift;
203
204     #always work with references
205     $fasta = $$fasta while(ref($fasta) eq 'REF');
206     my $fasta_ref = (ref($fasta) eq '') ? \$fasta : $fasta;
207
208     my @fasta = split(/\n/, $$fasta_ref);
209
210     my $seq = '';
211     while(my $l = shift(@fasta)){
212         chomp($l);
213         next if $l =~ /^>/;
214         $seq .= $l;
215     }
216
217     #remove contaminating whitespace
218     $seq =~ s/\s+//g;
219
220     return \$seq;
221 }
222 #-------------------------------------------------------------------------------
223 sub ucFasta{
224     my $fasta = shift;
225
226     return ${ucFastaRef(\$fasta)};
227 }
228 #-------------------------------------------------------------------------------
229 sub ucFastaRef{
230         my $fasta = shift;
231
232         #always work with references
233         $fasta = $$fasta while(ref($fasta) eq 'REF');
234         my $fasta_ref = (ref($fasta) eq '') ? \$fasta : $fasta;
235
236         my $def = getDef($fasta_ref);
237         my $seq = uc(getSeq($fasta_ref));
238
239         return toFastaRef($def, \$seq);
240 }
241 #-------------------------------------------------------------------------------
242 sub revComp {
243     my $seq = shift;
244
245     return ${revCompRef(\$seq)};
246 }
247 #-------------------------------------------------------------------------------
248 sub revCompRef {
249         my $seq = shift;
250
251         #always work with references
252         $seq = $$seq while(ref($seq) eq 'REF');
253         my $seq_ref = (ref($seq) eq '') ? \$seq : $seq;
254
255         my($rc);
256
257         $rc = $$seq_ref;
258         $rc =~ tr/acgtrymkswhbvdnxACGTRYMKSWHBVDNX
259                  /tgcayrkmswdvbhnxTGCAYRKMSWDVBHNX/;
260         $rc = reverse scalar ($rc);
261
262         return \$rc;
263 }
264 #-------------------------------------------------------------------------------
265 sub toFasta {
266     my $def = shift;
267     my $seq = shift;
268
269     return ${toFastaRef($def, \$seq)};
270 }
271 #-------------------------------------------------------------------------------
272 sub toFastaRef {
273         my $def = shift;
274         my $seq = shift;
275
276         #always work with references
277         $seq = $$seq while(ref($seq) eq 'REF');
278         my $seq_ref = (ref($seq) eq '') ? \$seq : $seq;
279
280         my $fasta = $def."\n";
281
282         $fasta .=  ${_formatSeq($seq_ref, 60)};
283
284         return \$fasta;
285 }
286 #-------------------------------------------------------------------------------
287 sub _formatSeq {
288         my $seq = shift;
289         my $l   = shift;
290
291         #always work with references
292         $seq = $$seq while(ref($seq) eq 'REF');
293         my $seq_ref = (ref($seq) eq '') ? \$seq : $seq;
294
295         my $f_seq = '';
296         for (my $i=0; $i< length($$seq_ref);$i+=$l){
297                 $f_seq .= substr($$seq_ref, $i, $l)."\n";
298         }
299
300         return \$f_seq;
301 }
302 #-------------------------------------------------------------------------------
303 sub toBpos {
304         my $def = shift;
305         my $seq = shift;
306
307         #always work with references
308         $seq = $$seq while(ref($seq) eq 'REF');
309         my $seq_ref = (ref($seq) eq '') ? \$seq : $seq;
310
311         my $fasta = $def."\n";
312
313         my $bpos = "0 " x length($$seq_ref);
314
315         for (my $i=0; $i< length($bpos);$i+=60){
316                 $fasta .= substr($bpos, $i, 60)."\n";
317         }
318
319         return $fasta;
320 }
321
322 #-------------------------------------------------------------------------------
323 sub toQual {
324         my $def = shift;
325         my $seq = shift;
326
327         #always work with references
328         $seq = $$seq while(ref($seq) eq 'REF');
329         my $seq_ref = (ref($seq) eq '') ? \$seq : $seq;
330
331         $$seq_ref  =~ s/^\s+//;
332
333         my @values = split(/\s+/, $$seq_ref);
334         my $fasta  = $def."\n";
335
336         my $j = 0;
337         for (my $i=0; $i< @values ;$i++){
338                 if ($j < 20){
339                         my $v = $values[$i];
340
341                         $fasta .= length($values[$i]) == 1 ? $values[$i]."  "
342                                                            : $values[$i]." ";
343                         $j++;
344                 }
345                 elsif ($j == 20){
346                         $fasta .= $values[$i]."\n";
347                         $j = 0;
348                 }
349                 else {
350                         die "dead in toQual\n";
351                 }
352         }
353         $fasta .= "\n" unless $fasta =~ /\n$/;
354
355         return $fasta;
356 }
357 #-------------------------------------------------------------------------------
358 sub shift2 (\@) {
359         return splice(@{$_[0]}, 0, 2);
360 }
361 #-------------------------------------------------------------------------------
362 sub AUTOLOAD {
363         my ($self, $arg) = @_;
364
365         my $caller = caller();
366         use vars qw($AUTOLOAD);
367         my ($call) = $AUTOLOAD =~/.*\:\:(\w+)$/;
368         $call =~/DESTROY/ && return;
369
370         print STDERR "Fasta::AutoLoader called for: ",
371               "\$self->$call","()\n";
372         print STDERR "call to AutoLoader issued from: ", $caller, "\n";
373
374         if (defined($arg)){
375                 $self->{$call} = $arg;
376         }
377         else {
378                 return $self->{$call};
379         }
380 }
381 #----------------------------------------------------------------------------
382
383 1;
Note: See TracBrowser for help on using the browser.