[bug 2714]
[bioperl-live.git] / Bio / AlignIO / psi.pm
blobbf81da84081b4577620a8e27056a94df530befd8
1 # $Id$
3 # BioPerl module for Bio::AlignIO::psi
5 # Cared for by Jason Stajich <jason@bioperl.org>
7 # Copyright Jason Stajich
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::AlignIO::psi - Read/Write PSI-BLAST profile alignment files
17 =head1 SYNOPSIS
19 This module will parse PSI-BLAST output of the format seqid XXXX
21 =head1 DESCRIPTION
23 This is a parser for psi-blast blocks.
25 =head1 FEEDBACK
27 =head2 Mailing Lists
29 User feedback is an integral part of the evolution of this and other
30 Bioperl modules. Send your comments and suggestions preferably to
31 the Bioperl mailing list. Your participation is much appreciated.
33 bioperl-l@bioperl.org - General discussion
34 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
36 =head2 Reporting Bugs
38 Report bugs to the Bioperl bug tracking system to help us keep track
39 of the bugs and their resolution. Bug reports can be submitted via
40 the web:
42 http://bugzilla.open-bio.org/
44 =head1 AUTHOR - Jason Stajich
46 Email jason@bioperl.org
48 =head1 APPENDIX
50 The rest of the documentation details each of the object methods.
51 Internal methods are usually preceded with a _
53 =cut
56 # Let the code begin...
59 package Bio::AlignIO::psi;
60 use vars qw($BlockLen $IdLength);
61 use strict;
63 $BlockLen = 100;
64 $IdLength = 13;
66 # Object preamble - inherits from Bio::Root::Root
68 use Bio::SimpleAlign;
69 use Bio::LocatableSeq;
71 use base qw(Bio::AlignIO);
73 =head2 new
75 Title : new
76 Usage : my $obj = Bio::AlignIO::psi->new();
77 Function: Builds a new Bio::AlignIO::psi object
78 Returns : Bio::AlignIO::psi
79 Args :
81 =cut
83 =head2 next_aln
85 Title : next_aln
86 Usage : $aln = $stream->next_aln()
87 Function: returns the next alignment in the stream
88 Returns : Bio::Align::AlignI object
89 Args : NONE
91 See L<Bio::Align::AlignI>
93 =cut
95 sub next_aln {
96 my ($self) = @_;
97 my $aln;
98 my %seqs;
99 my @order;
100 while( defined ($_ = $self->_readline ) ) {
101 next if( /^\s+$/);
102 if( !defined $aln ) {
103 $aln = Bio::SimpleAlign->new();
105 my ($id,$s) = split;
106 push @order, $id if( ! defined $seqs{$id});
107 $seqs{$id} .= $s;
109 foreach my $id ( @order) {
110 my $gaps = $seqs{$id} =~ tr/-/-/;
111 my $seq = Bio::LocatableSeq->new(-seq => $seqs{$id},
112 -id => $id,
113 -start => 1,
114 -end => length($seqs{$id}) - $gaps
116 $aln->add_seq($seq);
118 return $aln;
121 =head2 write_aln
123 Title : write_aln
124 Usage : $stream->write_aln(@aln)
125 Function: writes the NCBI psi-format object (.aln) into the stream
126 Returns : 1 for success and 0 for error
127 Args : Bio::Align::AlignI object
129 L<Bio::Align::AlignI>
131 =cut
133 sub write_aln {
134 my ($self,$aln) = @_;
135 unless( defined $aln && ref($aln) &&
136 $aln->isa('Bio::Align::AlignI') ) {
137 $self->warn("Must provide a valid Bio::Align::AlignI to write_aln");
138 return 0;
140 my $ct = 0;
141 my @seqs = $aln->each_seq;
142 my $len = 1;
143 my $alnlen = $aln->length;
144 my $idlen = $IdLength;
145 my @ids = map { substr($_->display_id,0,$idlen) } @seqs;
146 while( $len < ($alnlen + 1) ) {
147 my $start = $len;
148 my $end = $len + $BlockLen;
149 $end = $alnlen if ( $end > $alnlen );
150 my $c = 0;
151 foreach my $seq ( @seqs ) {
152 $self->_print(sprintf("%-".$idlen."s %s\n",
153 $ids[$c++],
154 $seq->subseq($start,$end)));
156 $self->_print("\n");
157 $len += $BlockLen+1;
159 $self->flush if $self->_flush_on_write && defined $self->_fh;
160 return 1;