File Coverage

Bio/Prospect/Thread.pm
Criterion Covered Total %
statement 44 413 10.6
branch 2 128 1.5
condition 1 13 7.6
subroutine 12 61 19.6
pod 40 43 93.0
total 99 658 15.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Bio::Prospect::Thread - Representation of a Prospect thread.
4            
5             S<$Id: Thread.pm,v 1.28 2003/11/18 19:45:45 rkh Exp $>
6              
7             =head1 SYNOPSIS
8              
9             my $in = new IO::File $ARGV[0] or die( "can't open $ARGV[0] for reading" );
10             my $out = new IO::File ">$ARGV[1]" or die( "can't open $ARGV[1] for writing" );
11             my $xml = '';
12             while(<$in>) { $xml .= $_; }
13             close($in);
14            
15             my $t = new Bio::Prospect::Thread( $xml );
16            
17             print "tseq: " . $t->tseq() . "\n";
18             print "qseq: " . $t->qseq() . "\n";
19             print "raw: " . $t->raw_score() . "\n";
20             print "svm: " . $t->svm_score() . "\n";
21             print "align: " . $t->alignment() . "\n";
22             $t->write_xml( $out );
23            
24             exit(0);
25              
26             =head1 DESCRIPTION
27              
28             Bio::Prospect::Thread -- Representation of a full Prospect thread
29             this is really just a set of methods associated with the hash structure
30             returned by XML::Simple.
31              
32             =cut
33              
34              
35             package Bio::Prospect::Thread;
36              
37 2     2   12 use strict;
  2         3  
  2         58  
38 2     2   9 use Carp;
  2         4  
  2         105  
39 2     2   2604 use XML::Simple;
  2         21249  
  2         15  
40 2     2   1961 use IO::String;
  2         5529  
  2         61  
41 2     2   2040 use Bio::Structure::IO;
  2         136519  
  2         82  
42 2     2   1981 use Bio::Structure::Entry;
  2         55147  
  2         71  
43 2     2   1799 use Bio::Symbol::ProteinAlphabet;
  2         10698  
  2         64  
44 2     2   742 use Bio::Prospect::Exceptions;
  2         7  
  2         74  
45             $XML::Simple::PREFERRED_PARSER = 'XML::Parser';
46              
47 2     2   11 use vars qw( $VERSION );
  2         4  
  2         11244  
48             $VERSION = sprintf( "%d.%02d", q$Revision: 1.28 $ =~ /(\d+)\.(\d+)/ );
49              
50              
51             =head1 METHODS
52              
53             =cut
54              
55              
56             #-------------------------------------------------------------------------------
57             # new()
58             #-------------------------------------------------------------------------------
59              
60             =head2 new()
61              
62             Name: new()
63             Purpose: return Thread object
64             Arguments: Prospect XML string
65             Returns: Bio::Prospect::Thread
66              
67             =cut
68              
69             sub new {
70 1     1 1 2 my $class = shift;
71 1         3 my $self = {};
72 1         3 bless $self,$class;
73 1   50     4 my $xml = shift || undef;
74 1 50       9 $self->{'xml'} = $xml if ( defined $xml );
75              
76             # store alignment info for threaded_structure support
77 1         3 $self->{'identities'} = {};
78 1         3 $self->{'similarities'} = {};
79 1         3 $self->{'mismatches'} = {};
80 1         4 $self->{'deletions'} = {};
81 1         3 $self->{'inserts'} = {};
82              
83 1         4 return( $self );
84             }
85              
86              
87              
88             #-------------------------------------------------------------------------------
89             # qname()
90             #-------------------------------------------------------------------------------
91              
92             =head2 qname()
93              
94             Name: qname()
95             Purpose: return the name of the query sequence
96             Arguments: none
97             Returns: string
98              
99             =cut
100              
101             sub qname {
102 1     1 1 447 my $self = shift;
103 1         5 $self->_parse_xml_file();
104 0         0 return $self->{'dom'}->{'source'};
105             }
106              
107              
108             #-------------------------------------------------------------------------------
109             # qseq()
110             #-------------------------------------------------------------------------------
111              
112             =head2 qseq()
113              
114             Name: qseq()
115             Purpose: return the query sequence
116             Arguments: none
117             Returns: string
118              
119             =cut
120              
121             sub qseq {
122 0     0 1 0 my $self = shift;
123 0         0 $self->_parse_xml_file();
124 0         0 return $self->{'dom'}->{'targetSeq'}->{'seq'};
125             }
126              
127              
128             #-------------------------------------------------------------------------------
129             # qseq_align()
130             #-------------------------------------------------------------------------------
131              
132             =head2 qseq_align()
133              
134             Name: qseq_align()
135             Purpose: return the aligned query sequence
136             Arguments: none
137             Returns: string
138              
139             =cut
140              
141             sub qseq_align {
142 0     0 1 0 my $self = shift;
143 0         0 $self->_parse_xml_file();
144 0         0 return $self->{'dom'}->{'alignment'}->{'target'};
145             }
146              
147              
148             #-------------------------------------------------------------------------------
149             # qss()
150             #-------------------------------------------------------------------------------
151              
152             =head2 qss()
153              
154             Name: qss()
155             Purpose: return the secondary structure of the aligned query sequence
156             Arguments: none
157             Returns: string
158              
159             =cut
160              
161             sub qss {
162 0     0 1 0 my $self = shift;
163 0         0 $self->_parse_xml_file();
164 0         0 return $self->{'dom'}->{'alignment'}->{'target_ss'};
165             }
166              
167              
168             #-------------------------------------------------------------------------------
169             # qlen()
170             #-------------------------------------------------------------------------------
171              
172             =head2 qlen()
173              
174             Name: qlen()
175             Purpose: return the length of the query sequence
176             Arguments: none
177             Returns: integer
178              
179             =cut
180              
181             sub qlen {
182 0     0 1 0 my $self = shift;
183 0         0 $self->_parse_xml_file();
184 0         0 return $self->{'dom'}->{'scoreInfo'}->{'seqLen'};
185             }
186              
187              
188             #-------------------------------------------------------------------------------
189             # qstart()
190             #-------------------------------------------------------------------------------
191              
192             =head2 qstart()
193              
194             Name: qstart()
195             Purpose: return the start of the alignment on the query sequence
196             Arguments: none
197             Returns: integer
198              
199             =cut
200              
201             sub qstart {
202 0     0 1 0 my $self = shift;
203 0         0 $self->_parse_xml_file();
204              
205             # the qstart is not correctly handled in the xml file. the value of
206             # alignmentInfo->targetFrom is really the start position of the query
207             # sequence, which we define as target_start. we'll calculate the qstart
208             # using the gaps inserted into the template sequence alignment (i.e. leading
209             # dashes).
210 0 0       0 if ( ! defined $self->{'dom'}->{'alignmentInfo'}->{'qstart'} ) {
211 0         0 $self->tseq_align() =~ m/^(-+)/;
212 0 0       0 my $len = ( defined $1 ) ? length($1) : 0;
213 0 0       0 printf STDERR "length: $len\n" if $ENV{DEBUG};
214 0         0 $self->{'dom'}->{'alignmentInfo'}->{'qstart'} = $self->target_start() + $len;
215             }
216 0         0 return $self->{'dom'}->{'alignmentInfo'}->{'qstart'};
217             }
218              
219              
220             #-------------------------------------------------------------------------------
221             # qend()
222             #-------------------------------------------------------------------------------
223              
224             =head2 qend()
225              
226             Name: qend()
227             Purpose: return the end of the alignment on the query sequence
228             Arguments: none
229             Returns: integer
230              
231             =cut
232              
233             sub qend {
234 0     0 1 0 my $self = shift;
235 0         0 $self->_parse_xml_file();
236              
237             # the qend is not defined in the xml. we'll use the qstart, alignment length,
238             # and gaps in the query alignment to calculate the position in the query
239             # at the end of the alignment
240 0 0       0 if ( ! defined $self->{'dom'}->{'alignmentInfo'}->{'qend'} ) {
241 0         0 my $align_len = $self->align_len();
242 0         0 my $aligned = substr $self->qseq_align(),$self->qstart()-1,$align_len;
243 0 0       0 print "qend(): len of aligned: " . length($aligned) . "\n" if $ENV{DEBUG};
244 0         0 my @gaps = ( $aligned =~ m/-/g );
245 0 0       0 print "qend(): number of gaps: " . scalar(@gaps) . "\n" if $ENV{DEBUG};
246 0         0 $self->{'dom'}->{'alignmentInfo'}->{'qend'} = $self->qstart() - scalar(@gaps) + $align_len - 1;
247             }
248 0         0 return $self->{'dom'}->{'alignmentInfo'}->{'qend'};
249             }
250              
251              
252             #-------------------------------------------------------------------------------
253             # target_start()
254             #-------------------------------------------------------------------------------
255              
256             =head2 target_start()
257              
258             Name: target_start()
259             Purpose: return the start position of the query sequence
260             Arguments: none
261             Returns: integer
262              
263             =cut
264              
265             sub target_start {
266 0     0 1 0 my $self = shift;
267 0         0 $self->_parse_xml_file();
268 0         0 return (1);
269             }
270              
271              
272             #-------------------------------------------------------------------------------
273             # target_end()
274             #-------------------------------------------------------------------------------
275              
276             =head2 target_end()
277              
278             Name: target_end()
279             Purpose: return the end position of the query sequence
280             Arguments: none
281             Returns: integer
282              
283             =cut
284              
285             sub target_end {
286 0     0 1 0 my $self = shift;
287 0         0 $self->_parse_xml_file();
288 0         0 return ($self->{'dom'}->{'scoreInfo'}->{'seqLen'});
289             }
290              
291              
292             #-------------------------------------------------------------------------------
293             # tname()
294             #-------------------------------------------------------------------------------
295              
296             =head2 tname()
297              
298             Name: tname()
299             Purpose: return the name of the template sequence
300             Arguments: none
301             Returns: string
302              
303             =cut
304              
305             sub tname {
306 0     0 1 0 my $self = shift;
307 0         0 $self->_parse_xml_file();
308 0         0 return $self->{'dom'}->{'templateName'};
309             }
310              
311              
312             #-------------------------------------------------------------------------------
313             # pdbcode()
314             #-------------------------------------------------------------------------------
315              
316             =head2 pdbcode()
317              
318             Name: pdbcode()
319             Purpose: return the PDB id
320             Arguments: none
321             Returns: string
322              
323             =cut
324              
325             sub pdbcode {
326 0     0 1 0 my $self = shift;
327 0         0 $self->_parse_xml_file();
328 0         0 return $self->{'dom'}->{'pdbcode'};
329             }
330              
331              
332             #-------------------------------------------------------------------------------
333             # tseq()
334             #-------------------------------------------------------------------------------
335              
336             =head2 tseq()
337              
338             Name: tseq()
339             Purpose: return the template sequence
340             Arguments: none
341             Returns: string
342              
343             =cut
344              
345             sub tseq {
346 0     0 1 0 my $self = shift;
347 0         0 $self->_parse_xml_file();
348 0         0 return $self->{'dom'}->{'templateSeq'}->{'seq'};
349             }
350              
351              
352             #-------------------------------------------------------------------------------
353             # tseq_align()
354             #-------------------------------------------------------------------------------
355              
356             =head2 tseq_align()
357              
358             Name: tseq_align()
359             Purpose: return the aligned template sequence
360             Arguments: none
361             Returns: string
362              
363             =cut
364              
365             sub tseq_align {
366 0     0 1 0 my $self = shift;
367 0         0 $self->_parse_xml_file();
368 0         0 return $self->{'dom'}->{'alignment'}->{'template'};
369             }
370              
371              
372             #-------------------------------------------------------------------------------
373             # tss()
374             #-------------------------------------------------------------------------------
375              
376             =head2 tss()
377              
378             Name: tss()
379             Purpose: return the secondary structure of the aligned template sequence
380             Arguments: none
381             Returns: string
382              
383             =cut
384              
385             sub tss {
386 0     0 1 0 my $self = shift;
387 0         0 $self->_parse_xml_file();
388 0         0 return $self->{'dom'}->{'alignment'}->{'template_ss'};
389             }
390              
391              
392             #-------------------------------------------------------------------------------
393             # tlen()
394             #-------------------------------------------------------------------------------
395              
396             =head2 tlen()
397              
398             Name: tlen()
399             Purpose: return the length of the template sequence
400             Arguments: none
401             Returns: integer
402              
403             =cut
404              
405             sub tlen {
406 0     0 1 0 my $self = shift;
407 0         0 $self->_parse_xml_file();
408 0         0 return $self->{'dom'}->{'scoreInfo'}->{'tempLen'};
409             }
410              
411              
412             #-------------------------------------------------------------------------------
413             # tstart()
414             #-------------------------------------------------------------------------------
415              
416             =head2 tstart()
417              
418             Name: tstart()
419             Purpose: return the start of the alignment on the template sequence.
420             CURRENTLY, tstart and template_start are the same. Because the
421             template residue numbering is not necessarily sequential (due
422             to missing residues in the structure), I would need
423             to parse the template xml files to correctly handle the
424             tstart value.
425             Arguments: none
426             Returns: integer
427              
428             =cut
429              
430             sub tstart {
431 0     0 1 0 my $self = shift;
432 0         0 $self->_parse_xml_file();
433 0         0 return( $self->template_start() );
434             }
435              
436              
437             #-------------------------------------------------------------------------------
438             # tend()
439             #-------------------------------------------------------------------------------
440              
441             =head2 tend()
442              
443             Name: tend()
444             Purpose: return the end of the alignment on the template sequence.
445             CURRENTLY, tend and template_start are the same. Because the
446             template residue numbering is not necessarily sequential (due
447             to missing residues in the structure), I would need
448             to parse the template xml files to correctly handle the
449             tend value.
450             Arguments: none
451             Returns: integer
452              
453             =cut
454              
455             sub tend {
456 0     0 1 0 my $self = shift;
457 0         0 $self->_parse_xml_file();
458 0         0 return( $self->template_end() );
459             }
460              
461              
462             #-------------------------------------------------------------------------------
463             # template_start()
464             #-------------------------------------------------------------------------------
465              
466             =head2 template_start()
467              
468             Name: template_start()
469             Purpose: return the start position of the template sequence
470             Arguments: none
471             Returns: integer
472              
473             =cut
474              
475             sub template_start {
476 0     0 1 0 my $self = shift;
477 0         0 $self->_parse_xml_file();
478 0         0 return $self->{'dom'}->{'alignmentInfo'}->{'templateFrom'};
479             }
480              
481              
482             #-------------------------------------------------------------------------------
483             # target_end()
484             #-------------------------------------------------------------------------------
485              
486             =head2 target_end()
487              
488             Name: target_end()
489             Purpose: return the end position of the template sequence
490             Arguments: none
491             Returns: integer
492              
493             =cut
494              
495             sub template_end {
496 0     0 0 0 my $self = shift;
497 0         0 $self->_parse_xml_file();
498 0         0 return $self->{'dom'}->{'alignmentInfo'}->{'templateTo'};
499             }
500              
501              
502             #-------------------------------------------------------------------------------
503             # isGlobal()
504             #-------------------------------------------------------------------------------
505              
506             =head2 isGlobal()
507              
508             Name: isGlobal()
509             Purpose: return whether the alignment is global (1) or local (0)
510             Arguments: none
511             Returns: integer
512              
513             =cut
514              
515             sub is_global {
516 0     0 0 0 my $self = shift;
517 0         0 $self->_parse_xml_file();
518 0         0 return $self->{'dom'}->{'settings'}->{'alignmentType'} eq 'global';
519             }
520              
521              
522             #-------------------------------------------------------------------------------
523             # align()
524             #-------------------------------------------------------------------------------
525              
526             =head2 raw_align()
527              
528             Name: align()
529             Purpose: return the raw alignment from the prospect output
530             Arguments: none
531             Returns: string
532              
533             =cut
534              
535             sub raw_align {
536 0     0 1 0 my $self = shift;
537 0         0 $self->_parse_xml_file();
538 0         0 return $self->{'dom'}->{'alignment'}->{'align'};
539             }
540              
541              
542             #-------------------------------------------------------------------------------
543             # align_len()
544             #-------------------------------------------------------------------------------
545              
546             =head2 align_len()
547              
548             Name: align_len()
549             Purpose: return the alignment length
550             Arguments: none
551             Returns: float
552              
553             =cut
554              
555             sub align_len {
556 0     0 1 0 my ($self) = shift;
557 0         0 $self->_parse_xml_file();
558 0         0 return ($self->{'dom'}->{'alignmentInfo'}->{'nalign'});
559             }
560              
561              
562             #-------------------------------------------------------------------------------
563             # identities()
564             #-------------------------------------------------------------------------------
565              
566             =head2 identities()
567              
568             Name: identities()
569             Purpose: return the number of identities
570             Arguments: none
571             Returns: float
572              
573             =cut
574              
575             sub identities {
576 0     0 1 0 my ($self) = shift;
577 0         0 $self->_parse_xml_file();
578 0         0 return ($self->{'dom'}->{'alignmentInfo'}->{'nident'});
579             }
580              
581              
582             #-------------------------------------------------------------------------------
583             # svm_score()
584             #-------------------------------------------------------------------------------
585              
586             =head2 svm_score()
587              
588             Name: svm_score()
589             Purpose: get/set the svm score
590             Arguments: none
591             Returns: float
592              
593             =cut
594              
595             sub svm_score {
596 0     0 1 0 my ($self,$score) = @_;
597 0         0 $self->_parse_xml_file();
598              
599 0 0       0 if ( defined $score ) { # acting as a mutator
600 0         0 $self->{'dom'}->{'scoreInfo'}->{'svmScore'} = $score;
601             } else { # acting as an accessor
602 0   0     0 return $self->{'dom'}->{'scoreInfo'}->{'svmScore'} || 'NA';
603             }
604             }
605              
606              
607             #-------------------------------------------------------------------------------
608             # raw_score()
609             #-------------------------------------------------------------------------------
610              
611             =head2 raw_score()
612              
613             Name: raw_score()
614             Purpose: return the raw score
615             Arguments: none
616             Returns: float
617              
618             =cut
619              
620             sub raw_score {
621 0     0 1 0 my $self = shift;
622 0         0 $self->_parse_xml_file();
623 0         0 return $self->{'dom'}->{'scoreInfo'}->{'rawScore'};
624             }
625              
626              
627             #-------------------------------------------------------------------------------
628             # gap_score()
629             #-------------------------------------------------------------------------------
630              
631             =head2 gap_score()
632              
633             Name: gap_score()
634             Purpose: return the gap score
635             Arguments: none
636             Returns: float
637              
638             =cut
639              
640             sub gap_score {
641 0     0 1 0 my $self = shift;
642 0         0 $self->_parse_xml_file();
643 0         0 return $self->{'dom'}->{'scoreInfo'}->{'gapPenalty'};
644             }
645              
646              
647             #-------------------------------------------------------------------------------
648             # mutation_score()
649             #-------------------------------------------------------------------------------
650              
651             =head2 mutation_score()
652              
653             Name: mutation_score()
654             Purpose: return the mutation score
655             Arguments: none
656             Returns: float
657              
658             =cut
659              
660             sub mutation_score {
661 0     0 1 0 my $self = shift;
662 0         0 $self->_parse_xml_file();
663 0         0 return $self->{'dom'}->{'scoreInfo'}->{'mutationScore'};
664             }
665              
666              
667             #-------------------------------------------------------------------------------
668             # ssfit_score()
669             #-------------------------------------------------------------------------------
670              
671             =head2 ssfit_score()
672              
673             Name: ssfit_score()
674             Purpose: return the ssfit score
675             Arguments: none
676             Returns: float
677              
678             =cut
679              
680             sub ssfit_score {
681 0     0 1 0 my $self = shift;
682 0         0 $self->_parse_xml_file();
683 0         0 return $self->{'dom'}->{'scoreInfo'}->{'ssfit'};
684             }
685              
686              
687             #-------------------------------------------------------------------------------
688             # pair_score()
689             #-------------------------------------------------------------------------------
690              
691             =head2 pair_score()
692              
693             Name: pair_score()
694             Purpose: return the pairwise score
695             Arguments: none
696             Returns: float
697              
698             =cut
699              
700             sub pair_score {
701 0     0 1 0 my $self = shift;
702 0         0 $self->_parse_xml_file();
703 0         0 return $self->{'dom'}->{'scoreInfo'}->{'pairwiseCore'};
704             }
705              
706              
707             #-------------------------------------------------------------------------------
708             # singleton_score()
709             #-------------------------------------------------------------------------------
710              
711             =head2 singleton_score()
712              
713             Name: singleton_score()
714             Purpose: return the singletonwise score
715             Arguments: none
716             Returns: float
717              
718             =cut
719              
720             sub singleton_score {
721 0     0 1 0 my $self = shift;
722 0         0 $self->_parse_xml_file();
723 0         0 return $self->{'dom'}->{'scoreInfo'}->{'singletonScore'};
724             }
725              
726              
727             #-------------------------------------------------------------------------------
728             # rgyr()
729             #-------------------------------------------------------------------------------
730              
731             =head2 rgyr()
732              
733             Name: rgyr()
734             Purpose: return the radius of gyration
735             Arguments: none
736             Returns: float
737              
738             =cut
739              
740             sub rgyr {
741 0     0 1 0 my $self = shift;
742 0         0 $self->_parse_xml_file();
743 0         0 return $self->{'dom'}->{'scoreInfo'}->{'radiusOfGyration'};
744             }
745              
746              
747             #-------------------------------------------------------------------------------
748             # alignment()
749             #-------------------------------------------------------------------------------
750              
751             =head2 alignment()
752              
753             Name: alignment()
754             Purpose: return the threading alignment as a set of line-wrapped rows.
755             Arguments: query tag (optional), template tag (optional), width (optional)
756             Returns: string
757              
758             =cut
759              
760             sub alignment {
761 0     0 1 0 my $self = shift;
762 0   0     0 my $qtag = shift || 'query';
763 0   0     0 my $ttag = shift || 'template';
764 0   0     0 my $width = shift || 60;
765 0         0 $self->_parse_xml_file();
766 0         0 my $al = $self->{'dom'}->{'alignment'};
767 0         0 my @tags = ($qtag, 'similarity', $ttag, "$ttag/ss");
768 0         0 my @seqs = ($al->{target}, # query sequence
769             $al->{align}, # alignment decorations
770             $al->{template}, # template sequence
771             $al->{template_ss}); # template SS
772 0         0 my $ti = 0; # index of target sequence
773              
774 0 0       0 if (not ref $al->{target_ss}) {
775 0         0 unshift(@tags, "$qtag/ss");
776 0         0 unshift(@seqs, $al->{target_ss});
777 0         0 $ti++;
778             }
779              
780 0         0 @seqs = map {chomp($_);$_;} @seqs;
  0         0  
  0         0  
781              
782 0         0 my $rv = '';
783 0         0 my $taglen = 15;
784 0         0 my $qi = 0;
785 0         0 my $coord_init = '|%-'.($width-1).'d';
786 0         0 while ( length($seqs[$ti]) ) {
787             # build query coordinate line
788 0         0 my $ss = substr($seqs[$ti],0,$width);
789 0         0 my $coords = ' ' x $width;
790 0         0 for(my ($i,$lti)=(0,undef); $i<length($ss); $i++) {
791 0 0       0 next if (substr($ss,$i,1) eq '-');
792 0         0 $qi++;
793 0 0       0 print(STDERR "i=$i qi=$qi") if $ENV{'DEBUG'};
794 0 0 0     0 if (not defined $lti) {
    0          
795 0         0 my $c = sprintf("|%d",$qi);
796 0         0 my $lc = length($c);
797 0         0 substr($coords, $i, $lc, $c);
798 0         0 $lti = $i;
799 0 0       0 print(STDERR ": c=$c lc=$lc $coords") if $ENV{'DEBUG'};
800             } elsif ( ($qi % 10 == 0) and ($i-$lti >= 9) ) {
801 0         0 my $c = sprintf("%d|",$qi);
802 0         0 my $lc = length($c);
803 0         0 substr($coords, $i-$lc+1, $lc, $c);
804 0         0 $lti = $i;
805 0 0       0 print(STDERR ": lti=$lti c=$c lc=$lc $coords") if $ENV{'DEBUG'};
806             }
807 0 0       0 print(STDERR "\n") if $ENV{'DEBUG'}
808             }
809 0         0 $rv .= sprintf("%$taglen.${taglen}s $coords\n", 'query pos.');
810              
811 0         0 for(my $i=0;$i<=$#seqs;$i++) {
812 0         0 $rv .= sprintf("%$taglen.${taglen}s %s\n",
813             $tags[$i],substr($seqs[$i],0,$width,''));
814             }
815 0 0       0 $rv .= "\n" if $seqs[$ti];
816             }
817 0         0 return $rv;
818             }
819              
820              
821             #-------------------------------------------------------------------------------
822             # write_xml()
823             #-------------------------------------------------------------------------------
824              
825             =head2 write_xml()
826              
827             Name: write_xml()
828             Purpose: output the xml to a file
829             Arguments: IO::File object
830             Returns: none
831              
832             =cut
833              
834             sub write_xml {
835 0     0 1 0 my $self = shift;
836 0         0 my $out = shift;
837              
838 0         0 $self->_parse_xml_file();
839              
840 0         0 print $out $self->{'parser'}->XMLout( $self->{'dom'}, 'rootname' => 'threading' );
841             }
842              
843              
844             #-------------------------------------------------------------------------------
845             # output_rasmol_script()
846             #-------------------------------------------------------------------------------
847              
848             =head2 output_rasmol_script()
849              
850             Name: output_rasmol_script
851             Purpose: return a rasmol script for displaying a threaded structure
852             Arguments: Bio::Structure::IO::Entry object
853             Returns: rasmol script
854              
855             =cut
856              
857             sub output_rasmol_script {
858 0     0 1 0 my $self = shift;
859 0         0 my $struc = shift;
860              
861 0         0 my $stringio;
862              
863             # transform the pdb structure using the threaded alignment
864 0         0 $self->thread_structure( $struc );
865              
866             #----------------------------------------------------------------------
867             # use pdbBackbone for pdb coordinates - prefer using convertProspect
868             # pdb files instead (they include deletions in the template structure).
869             # leave this code here for now.
870             #
871             # if coordinates are not defined then we can't output a proper
872             # rasmol script
873             #my $coord = $self->pdb_model();
874             #if ( ! defined $coord ) {
875             #throw Bio::Prospect::RuntimeError(
876             #'No 3D coordinates available for this threading',
877             #'No 3D coordinates available in the prospect output for this threading',
878             #'Re-run prospect using the -3d flag'
879             #);
880             #}
881             #$self->_parse_structure( $coord );
882             #----------------------------------------------------------------------
883              
884 0         0 my $retval;
885 0         0 $stringio = IO::String->new($retval);
886              
887 0         0 $stringio->print("echo 'Generated by:'\n",
888             'echo \' $Id: Thread.pm,v 1.28 2003/11/18 19:45:45 rkh Exp $\'', "\n", # '
889             "echo\n"
890             );
891              
892             ## generate the alignment and echo it in the RasMol window
893 0         0 my $alignment = $self->alignment();
894 0         0 chomp($alignment);
895 0         0 $alignment =~ s/^.*$/echo '$&'/gm;
896 0         0 $stringio->print("echo 'Alignment:'\n",
897             $alignment, "\n");
898              
899             ## color the identities, similarities, mismatches
900             ## simultaneously selects/colors and echos the legend
901 0         0 $stringio->print("load pdb inline\n", # must load before selecting
902             "echo \n",
903             "echo 'Legend:'\n",
904             "echo ' set names in quotes may be used with select'\n");
905 0         0 my @select_me;
906 0 0       0 if ( @select_me = $self->get_identities() ) {
907 0         0 my @deco = ('cartoons','color blue');
908 0         0 $stringio->print( $self->_format_select( @select_me ),
909             "define identities selected\n",
910 0         0 map { "$_\n" } 'wireframe off',@deco );
911 0         0 $stringio->printf("echo ' %d \"identities\" decorated {%s}'\n",
912             $#select_me+1, join(',',@deco));
913             }
914              
915 0 0       0 if ( @select_me = $self->get_similarities() ) {
916 0         0 my @deco = ('cartoons','color cyan');
917 0         0 $stringio->print( $self->_format_select( @select_me ),
918             "define similarities selected\n",
919 0         0 map { "$_\n" } 'wireframe off',@deco );
920 0         0 $stringio->printf("echo ' %d \"similarities\" decorated {%s}'\n",
921             $#select_me+1, join(',',@deco));
922             }
923              
924 0 0       0 if ( @select_me = $self->get_mismatches() ) {
925 0         0 my @deco = ('cartoons','color red');
926 0         0 $stringio->print( $self->_format_select( @select_me ),
927             "define mismatches selected\n",
928 0         0 map { "$_\n" } 'wireframe off',@deco );
929 0         0 $stringio->printf("echo ' %d \"mismatches\" decorated {%s}'\n",
930             $#select_me+1, join(',',@deco));
931             }
932              
933 0 0       0 if ( @select_me = $self->get_deletions() ) {
934 0         0 my @deco = ('trace','color grey');
935 0         0 $stringio->print( $self->_format_select( @select_me ),
936             "define deletions selected\n",
937 0         0 map { "$_\n" } 'wireframe off',@deco );
938 0         0 $stringio->printf( "echo ' %d query \"deletions\" (template insertions) decorated {%s}'\n",
939             $#select_me+1, join(',',@deco) );
940             }
941              
942 0 0       0 if ( @select_me = $self->get_inserts() ) {
943 0         0 my @deco = ('strands','color green');
944 0         0 $stringio->print( $self->_format_select( @select_me ),
945             "define insertions selected\n",
946             "select selected and *.CA\n",
947 0         0 map { "$_\n" } 'wireframe off',@deco );
948 0         0 $stringio->printf( "echo ' %d query \"insertions\" (template deletions) decorated {%s}'\n",
949             $#select_me+1, join(',',@deco) );
950              
951             # label the inserts
952             #wrong: $stringio->printf("echo ' %d inserts at QUERY positions {%s}'\n",
953             #wrong: $#select_me+1, join(',',@select_me));
954 0         0 foreach my $ires_i (@select_me) {
955 0         0 my (@I) = $self->get_inserted_residues($ires_i);
956 0         0 my $I = join('',@I);
957 0         0 $I =~ s/\d//g; # remove residue numbers
958 0 0       0 if (length($I) > 20) {
959 0         0 $I = substr($I,0,10) . ' ... ' . substr($I,-10,10);
960             }
961 0         0 $stringio->printf("select %d and *.CA\nlabel '>%d AA<'\n", $ires_i, $#I+1);
962             #okay: $stringio->printf("echo ' %3d AA insert: %s'\n", $#I+1, $I);
963             }
964              
965 0         0 $stringio->print("set fontstroke 1\n",
966             "set fontsize 14\n");
967             }
968              
969 0         0 $stringio->print("select CYS\n",
970             "color yellow\n",
971             "select CYS and identities\n",
972             "spacefill\n",
973             "echo ' all CYS are yellow; conserved CYS are spacefilled'\n",
974             "exit\n");
975              
976             #----------------------------------------------------------------------
977             # use pdbBackbone for pdb coordinates - prefer using convertProspect
978             # pdb files instead (they include deletions in the template structure).
979             # leave this code here for now.
980             #
981             # print $stringio $coord;
982             #----------------------------------------------------------------------
983              
984 0         0 my $out = Bio::Structure::IO->new('-fh' => $stringio, '-format' => 'pdb');
985 0         0 $out->write_structure( $struc );
986              
987 0         0 return( $retval );
988             }
989              
990              
991             #-------------------------------------------------------------------------------
992             # thread_structure()
993             #-------------------------------------------------------------------------------
994              
995             =head2 thread_structure()
996              
997             Name: thread_structure
998             Purpose: modify a Bio::Structure::IO::Entry object to reflect a prospect
999             threading alignment
1000             Arguments: Bio::Prospect::Thread object, Bio::Structure::IO::Entry object
1001             Returns: nada
1002              
1003             =cut
1004              
1005             sub thread_structure {
1006 0     0 1 0 my $self = shift;
1007 0         0 my $templateStructure = shift;
1008              
1009 0         0 my $res;
1010             my $resname;
1011 0         0 my $resseq;
1012              
1013 0         0 my @template_align = split '', $self->tseq_align();
1014 0         0 my @target_align = split '', $self->qseq_align();
1015 0         0 my @alignment = split '', $self->raw_align();
1016              
1017 0 0       0 throw Bio::Prospect::RuntimeError( "templateStructure not right" )
1018             if ( ! $templateStructure->isa('Bio::Structure::Entry' ));
1019              
1020             # better error-handling
1021 0 0       0 if ( $#template_align != $#target_align ) {
1022 0         0 die("rut-row george (template length != target length)\n");
1023             }
1024              
1025 0         0 my $res_i= 0;
1026 0         0 my $start = $self->tstart();
1027 0         0 my $end = $self->tend();
1028 0         0 foreach my $model ( $templateStructure->get_models( $templateStructure ) ) {
1029 0         0 foreach my $chain ( $templateStructure->get_chains( $model ) ) {
1030 0         0 my @residues = $templateStructure->get_residues( $chain );
1031 0         0 foreach $res ( @residues ) {
1032 0         0 ($resname,$resseq) = split '-', $res->id();
1033 0 0       0 last if ( $resseq == $start );
1034 0         0 $res_i++;
1035             }
1036              
1037 0         0 for (my $i=0; $i<=$#template_align; $i++) {
1038 0         0 $res = $residues[$res_i];
1039 0         0 ($resname,$resseq) = split '-', $res->id();
1040              
1041 0 0       0 print STDERR "target: $target_align[$i]\n" if $ENV{'DEBUG'};
1042 0 0       0 print STDERR "template: $template_align[$i]\n" if $ENV{'DEBUG'};
1043              
1044 0 0       0 if ( $template_align[$i] eq '-' ) {
    0          
    0          
    0          
1045             # template insert
1046 0         0 $self->_add_insert( $resseq, "$target_align[$i]$i" );
1047 0 0       0 print STDERR "found insert\n" if $ENV{'DEBUG'};
1048 0         0 next;
1049             }
1050             elsif ( $target_align[$i] eq '-' ) {
1051             # template deletion
1052 0         0 $self->_add_deletion( $resseq );
1053 0 0       0 print STDERR "found deletion\n" if $ENV{'DEBUG'};
1054 0         0 $res_i++;
1055 0         0 next;
1056             }
1057             elsif ( $target_align[$i] eq $template_align[$i] ) {
1058             # identity
1059 0 0       0 if ( $alignment[$i] ne '|' ) {
1060 0         0 throw Bio::Prospect::RuntimeError(
1061             "thought it was a mismatch but align char is: [$alignment[$i]]\n" );
1062             }
1063 0         0 $self->_add_identity( $resseq );
1064 0         0 $res_i++;
1065              
1066             } elsif ( $target_align[$i] ne $template_align[$i] ) {
1067             # mismatch
1068 0 0       0 if ( $alignment[$i] ne '.' ) {
1069 0         0 $self->_add_similarity( $resseq );
1070             } else {
1071 0         0 $self->_add_mismatch( $resseq );
1072             }
1073 0         0 $res->id( $self->_a_to_aaa_code( $target_align[$i] ) . "-$resseq" );
1074 0         0 $res_i++;
1075              
1076             } else {
1077             # shouldn't happen
1078 0         0 print "ERROR - shouldn't have gotten here\n";
1079             }
1080              
1081 0 0       0 if ( $self->_a_to_aaa_code( $template_align[$i] ) ne $resname ) {
1082 0         0 throw Bio::Prospect::RuntimeError( "ERROR - template (" .
1083             $self->_a_to_aaa_code( $template_align[$i] ) .
1084             ") not equal to structure ($resname), resseq: $resseq\n" );
1085             }
1086              
1087 0 0       0 last if ( $resseq == $end );
1088             }
1089             }
1090             }
1091              
1092 0         0 return();
1093             }
1094              
1095              
1096             #-------------------------------------------------------------------------------
1097             # get_mismatches()
1098             #-------------------------------------------------------------------------------
1099              
1100             =head2 get_mismatches()
1101              
1102             Name: get_mismatches
1103             Purpose: return array of mismatches
1104             Argument: nada
1105             Returns: array of residue ids
1106              
1107             =cut
1108              
1109             sub get_mismatches {
1110 0     0 1 0 my $self = shift;
1111              
1112 0         0 return( sort { $a <=> $b } keys %{$self->{'mismatches'}} );
  0         0  
  0         0  
1113             }
1114              
1115              
1116             #-------------------------------------------------------------------------------
1117             # get_similarities()
1118             #-------------------------------------------------------------------------------
1119              
1120             =head2 get_similarities()
1121              
1122             Name: get_similarities
1123             Purpose: return array of similarities
1124             Argument: nada
1125             Returns: array of residue ids
1126              
1127             =cut
1128              
1129             sub get_similarities {
1130 0     0 1 0 my $self = shift;
1131              
1132 0         0 return( sort { $a <=> $b } keys %{$self->{'similarities'}} );
  0         0  
  0         0  
1133             }
1134              
1135              
1136             #-------------------------------------------------------------------------------
1137             # get_deletions()
1138             #-------------------------------------------------------------------------------
1139              
1140             =head2 get_deletions()
1141              
1142             Name: get_deletions
1143             Purpose: return array of deletions
1144             Argument: nada
1145             Returns: array of residue ids
1146              
1147             =cut
1148              
1149             sub get_deletions {
1150 0     0 1 0 my $self = shift;
1151              
1152 0         0 return( sort { $a <=> $b } keys %{$self->{'deletions'}} );
  0         0  
  0         0  
1153             }
1154              
1155              
1156             #-------------------------------------------------------------------------------
1157             # get_inserts()
1158             #-------------------------------------------------------------------------------
1159              
1160             =head2 get_inserts()
1161              
1162             Name: get_inserts
1163             Purpose: return array of inserts
1164             Argument: nada
1165             Returns: array of residue ids
1166              
1167             =cut
1168              
1169             sub get_inserts {
1170 0     0 1 0 my $self = shift;
1171 0         0 return( sort { $a <=> $b } keys %{$self->{'inserts'}} );
  0         0  
  0         0  
1172             }
1173              
1174              
1175             #-------------------------------------------------------------------------------
1176             # get_inserted_residues()
1177             #-------------------------------------------------------------------------------
1178              
1179             =head2 get_inserts()
1180              
1181             Name: get_inserted_residues
1182             Purpose: return identities of inserted residues
1183             Argument: position of insert
1184             Returns: array of residue ids
1185              
1186             =cut
1187              
1188             sub get_inserted_residues {
1189 0     0 0 0 my $self = shift;
1190 0         0 my $res_i = shift;
1191 0 0       0 if (exists $self->{inserted}[$res_i])
1192 0         0 { return @{ $self->{inserted}[$res_i] } }
  0         0  
1193 0         0 return ();
1194             }
1195              
1196              
1197             #-------------------------------------------------------------------------------
1198             # get_identities()
1199             #-------------------------------------------------------------------------------
1200              
1201             =head2 get_identities()
1202              
1203             Name: get_identities
1204             Purpose: return array of identities
1205             Argument: nada
1206             Returns: array of residue ids
1207              
1208             =cut
1209              
1210             sub get_identities {
1211 0     0 1 0 my $self = shift;
1212              
1213 0         0 return( sort { $a <=> $b } keys %{$self->{'identities'}} );
  0         0  
  0         0  
1214             }
1215              
1216              
1217             #-------------------------------------------------------------------------------
1218             # pdb_model()
1219             #-------------------------------------------------------------------------------
1220              
1221             =head2 pdb_model()
1222              
1223             Name: pdb_model()
1224             Purpose: return a rudimentary 3D backbone model in PDB format
1225             Arguments: none
1226             Returns: text
1227              
1228             =cut
1229              
1230             sub pdb_model {
1231 0     0 1 0 my $self = shift;
1232 0         0 $self->_parse_xml_file();
1233 0         0 return $self->{'dom'}->{'pdbBackbone'};
1234             }
1235              
1236              
1237             #-------------------------------------------------------------------------------
1238             # INTERNAL METHODS - not intended for use outside this module
1239             #-------------------------------------------------------------------------------
1240              
1241             #-------------------------------------------------------------------------------
1242             # _add_similarity()
1243             #-------------------------------------------------------------------------------
1244              
1245             =head2 _add_similarity()
1246              
1247             Name: _add_similarity
1248             Purpose: add residue id to list of similarities
1249             Arguments: residue id
1250             Returns: nada
1251              
1252             =cut
1253              
1254             sub _add_similarity {
1255 0     0   0 my $self = shift;
1256 0         0 my $resseq = shift;
1257              
1258 0 0       0 print STDERR "push $resseq onto similarity stack\n" if $ENV{'DEBUG'};
1259              
1260 0         0 $self->{'similarities'}->{$resseq}++;
1261             }
1262              
1263              
1264             #-------------------------------------------------------------------------------
1265             # _add_mismatch()
1266             #-------------------------------------------------------------------------------
1267              
1268             =head2 _add_mismatch()
1269              
1270             Name: _add_mismatch
1271             Purpose: add residue id to list of mismatches
1272             Arguments: residue id
1273             Returns: nada
1274              
1275             =cut
1276              
1277             sub _add_mismatch {
1278 0     0   0 my $self = shift;
1279 0         0 my $resseq = shift;
1280              
1281 0 0       0 print STDERR "push $resseq onto mismatch stack\n" if $ENV{'DEBUG'};
1282              
1283 0         0 $self->{'mismatches'}->{$resseq}++;
1284             }
1285              
1286              
1287             #-------------------------------------------------------------------------------
1288             # _add_deletion()
1289             #-------------------------------------------------------------------------------
1290              
1291             =head2 _add_deletion()
1292              
1293             Name: _add_deletion
1294             Purpose: add residue id to list of deletions
1295             Arguments: residue id
1296             Returns: nada
1297              
1298             =cut
1299              
1300             sub _add_deletion {
1301 0     0   0 my $self = shift;
1302 0         0 my $resseq = shift;
1303              
1304 0 0       0 print STDERR "push $resseq onto deletion stack\n" if $ENV{'DEBUG'};
1305              
1306 0         0 $self->{'deletions'}->{$resseq}++;
1307             }
1308              
1309              
1310             #-------------------------------------------------------------------------------
1311             # _add_insert()
1312             #-------------------------------------------------------------------------------
1313              
1314             =head2 _add_insert($$;@)
1315              
1316             Name: _add_insert
1317             Purpose: add residue id to list of inserts
1318             Arguments: template residue id at which insert occurs
1319             optional: inserted query residues
1320             Returns: nada
1321              
1322             =cut
1323              
1324             sub _add_insert {
1325 0     0   0 my $self = shift;
1326 0         0 my $resseq = shift;
1327              
1328 0 0       0 print STDERR "push $resseq onto insert stack\n" if $ENV{'DEBUG'};
1329              
1330 0         0 $self->{'inserts'}->{$resseq}++;
1331              
1332             # remaining args in @_ are the query residues which were inserted
1333 0 0       0 push(@{$self->{'inserted'}[$resseq]},@_) if (@_);
  0         0  
1334             }
1335              
1336              
1337             #-------------------------------------------------------------------------------
1338             # _add_identity()
1339             #-------------------------------------------------------------------------------
1340              
1341             =head2 _add_identity()
1342              
1343             Name: _add_identity
1344             Purpose: add residue id to list of identities
1345             Arguments: residue id
1346             Returns: nada
1347              
1348             =cut
1349              
1350             sub _add_identity {
1351 0     0   0 my $self = shift;
1352 0         0 my $resseq = shift;
1353              
1354 0 0       0 print STDERR "push $resseq onto identity stack\n" if $ENV{'DEBUG'};
1355              
1356 0         0 $self->{'identities'}->{$resseq}++;
1357             }
1358              
1359              
1360             #-------------------------------------------------------------------------------
1361             # _a_to_aaa_code()
1362             #-------------------------------------------------------------------------------
1363              
1364             =head2 _a_to_aaa_code()
1365              
1366             Name: _a_to_aaa_code
1367             Purpose: convert a single amino acid code (e.g. W) to its three letter
1368             amino acid code (e.g. TRP)
1369             Arguments: single amino acid code
1370             Returns: triple amino acid code
1371              
1372             =cut
1373              
1374             sub _a_to_aaa_code {
1375 0     0   0 my $self = shift;
1376 0         0 my $a = shift;
1377              
1378 0 0       0 if ( ! defined $self->{'a2aaa'} ) {
1379 0         0 my $alpha = new Bio::Symbol::ProteinAlphabet();
1380 0         0 foreach my $symbol ( $alpha->symbols ) {
1381 0         0 $self->{'a2aaa'}->{ $symbol->token() } = uc( $symbol->name() );
1382             }
1383             }
1384 0         0 return( $self->{'a2aaa'}->{$a} );
1385             }
1386              
1387              
1388             #-------------------------------------------------------------------------------
1389             # _format_select()
1390             #-------------------------------------------------------------------------------
1391              
1392             =head2 _format_select()
1393              
1394             Name: _format_select
1395             Purpose: handle the rasmol buffer limit
1396             Arguments: array of ids to select
1397             Returns: rasmol select statement
1398              
1399             =cut
1400              
1401             sub _format_select {
1402 0     0   0 my $self = shift;
1403 0         0 my @ids = @_;
1404 0         0 my $bin = 25;
1405 0         0 my $cnt = 0;
1406 0         0 my $retval = '';
1407 0         0 for( my $i=0; $i<=$#ids; $i+=$bin ) {
1408 0 0       0 my $end = ( $i + $bin < $#ids ) ? $i+$bin-1 : $#ids;
1409 0         0 $retval .= "define TEMP$cnt " . ( join ',', @ids[$i .. $end] ) . "\n";
1410 0         0 $cnt++;
1411             }
1412 0         0 $retval .= "select " . join(' or ',map { 'TEMP'.$_ } (0..$cnt-1) ) . "\n";
  0         0  
1413 0         0 return( $retval );
1414             }
1415              
1416              
1417             #-------------------------------------------------------------------------------
1418             # _parse_xml_file()
1419             #-------------------------------------------------------------------------------
1420              
1421             =head2 _parse_xml_file()
1422              
1423             Name: _parse_xml_file()
1424             Purpose: parse the input XML file.
1425             Arguments: [self]
1426             Returns: self
1427              
1428             =cut
1429              
1430             sub _parse_xml_file {
1431 1     1   2 my $self = shift;
1432              
1433             # only parse once. have every accessor method call
1434             # _parse_xml_file rather than having this method called from the
1435             # constructor (i.e. only do the xml parse if you need
1436             # something from the xml).
1437 1 50       4 return if defined $self->{'dom'};
1438              
1439 1         9 $self->{'parser'} = new XML::Simple;
1440 1         74 my $dom = $self->{'parser'}->XMLin( $self->{'xml'} );
1441 0           $self->{'dom'} = $dom;
1442              
1443             # don't store both the dom and xml
1444 0           undef $self->{'xml'};
1445              
1446 0           return $self;
1447             }
1448              
1449              
1450             #-------------------------------------------------------------------------------
1451             # _parse_structure()
1452             #-------------------------------------------------------------------------------
1453              
1454             =head2 _parse_structure()
1455              
1456             Name: _parse_structure
1457             Purpose: parse the pdb model and determine identities, similarities, deletions
1458             Arguments: scalar containing coordinates in pdb format
1459             Returns: nada
1460              
1461             =cut
1462              
1463             sub _parse_structure {
1464 0     0     my $self = shift;
1465 0           my $pdb = shift;
1466              
1467 0           my $res;
1468             my $resname;
1469 0           my $resseq;
1470              
1471 0           my $atom_unpack = "x6 a5 x1 a4 a1 a3 x1 a1 a4 a1 x3 a8 a8 a8 a6 a6";
1472              
1473 0           my @template_align = split '', $self->tseq_align();
1474 0           my @target_align = split '', $self->qseq_align();
1475 0           my @alignment = split '', $self->raw_align();
1476 0           my $end = $self->{'dom'}->{'alignmentInfo'}->{'targetTo'};
1477              
1478 0 0         throw Bio::Prospect::RuntimeError(
1479             "template alignment is not the same length as target alignment"
1480             ) if ( $#template_align != $#target_align );
1481              
1482 0           my %res_hash;
1483 0           foreach my $line ( split /\n/, $pdb ) {
1484 0 0         next if $line !~ m/^(ATOM |HETATM|SIGATM)/;
1485 0           my @fld = unpack $atom_unpack, $line;
1486 0           $fld[3] =~ s/\s+//g; $fld[5] =~ s/\s+//g;
  0            
1487 0           $res_hash{ $fld[5] } = $fld[3];
1488             }
1489 0           my @residues = map { $res_hash{$_} . '-' . $_ } sort {$a<=>$b} keys %res_hash;
  0            
  0            
1490            
1491 0           my $res_i= 0;
1492 0           my $start = $self->tstart();
1493              
1494 0           for (my $i=0; $i<=$#template_align; $i++) {
1495 0           ($resname,$resseq) = split '-', $residues[$res_i];
1496              
1497 0 0         print STDERR "resname: $resname\n" if $ENV{'DEBUG'};
1498 0 0         print STDERR "resseq: $resseq\n" if $ENV{'DEBUG'};
1499 0 0         print STDERR "target: $target_align[$i]\n" if $ENV{'DEBUG'};
1500 0 0         print STDERR "template: $template_align[$i]\n" if $ENV{'DEBUG'};
1501              
1502             # template insert
1503 0 0         if ( $template_align[$i] eq '-' ) {
    0          
    0          
    0          
1504 0           $self->_add_insert( $resseq, "$target_align[$i]$i" );
1505 0 0         print STDERR "found insert\n" if $ENV{'DEBUG'};
1506             #$res_i++;
1507 0           next;
1508             }
1509             # template deletion
1510             elsif ( $target_align[$i] eq '-' ) {
1511             # $self->_add_deletion( $resseq );
1512 0 0         print STDERR "found deletion\n" if $ENV{'DEBUG'};
1513             #$res_i++;
1514 0           next;
1515             }
1516             # identity
1517             elsif ( $target_align[$i] eq $template_align[$i] ) {
1518 0 0         if ( $alignment[$i] ne '|' ) {
1519 0           throw Bio::Prospect::RuntimeError(
1520             "thought it was a mismatch but align char is: [$alignment[$i]]\n" );
1521             }
1522 0           $self->_add_identity( $resseq );
1523 0           $res_i++;
1524              
1525             } elsif ( $target_align[$i] ne $template_align[$i] ) {
1526             # mismatch
1527 0 0         if ( $alignment[$i] ne '.' ) {
1528 0           $self->_add_similarity( $resseq );
1529             } else {
1530 0           $self->_add_mismatch( $resseq );
1531             }
1532 0           $res_i++;
1533             }
1534 0 0         if ( $self->_a_to_aaa_code( $target_align[$i] ) ne $resname ) {
1535 0           throw Bio::Prospect::RuntimeError( "ERROR - target (" .
1536             $self->_a_to_aaa_code( $target_align[$i] ) .
1537             ") not equal to structure ($resname), resseq: $resseq\n" );
1538             }
1539 0 0         last if ( $resseq == $end );
1540             }
1541 0           return();
1542             }
1543              
1544              
1545              
1546             1;