1 /* $Id: build_ares.c $ */
2 
3 /* copyright (c) 2010, 2014 by William R. Pearson and The Rector &
4    Vistors of the University of Virginia */
5 
6 /* Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9 
10    http://www.apache.org/licenses/LICENSE-2.0
11 
12    Unless required by applicable law or agreed to in writing,
13    software distributed under this License is distributed on an "AS
14    IS" BASIS, WITHOUT WRRANTIES OR CONDITIONS OF ANY KIND, either
15    express or implied.  See the License for the specific language
16    governing permissions and limitations under the License.
17 */
18 
19 /* build_ares_code is called by showbest() (in threaded/serial code) or
20    p2_workcomp in PCOMPLIB code to produce the cur_ares-> chain that
21    is displayed in showbest().
22 
23    For PCOMPLIB, the cur_ares->chain is passed to bbp->a_res by
24    do_stage2(), where it is available to showbest();
25 
26    By using this code, the a_res chain used in either mode will be the
27    same, so the code required to display an a_res should be the same.
28  */
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "defs.h"
35 #include "structs.h"
36 #include "param.h"
37 
38 /* #include "mm_file.h" */
39 #include "best_stats.h"
40 
41 #include "drop_func.h"
42 
43 extern void calc_coord(int n0, int n1, long qoffset, long loffset,
44 		      struct a_struct *aln);
45 
46 extern void calc_astruct(struct a_struct *aln_p, struct a_res_str *a_res_p, void *f_str);
47 
48 /* in build_ares_code, *aa1 is separate from *seq because *seq has
49    permanent information about aa1, but aa1 may be temporary */
50 
51 struct a_res_str *
build_ares_code(unsigned char * aa0,int n0,unsigned char * aa1,struct seq_record * seq,int frame,int * have_ares,int repeat_thresh,const struct mngmsg * m_msp,struct pstruct * ppst,void * f_str)52 build_ares_code(unsigned char *aa0, int n0,
53 		unsigned char *aa1, struct seq_record *seq,
54 		int frame, int *have_ares, int repeat_thresh,
55 		const struct mngmsg *m_msp, struct pstruct *ppst,
56 		void *f_str
57 		)
58 {
59   unsigned char *aa1_ann;
60   struct rstruct rst;
61   struct a_res_str *my_ares_p, *cur_ares_p;
62   struct a_struct *aln_p;
63   struct dyn_string_str *annot_var_dyn, *annot_code_dyn;
64   long loffset;		/* loffset is offset from beginning of real sequence */
65   long l_off;		/* l_off is the the virtual coordinate of residue 1 */
66   int seqc_max, annc_max;
67   char *seq_code;
68   int seq_code_len, ann_code_len;
69   int score_delta;
70 
71   annot_var_dyn = init_dyn_string(2048, 2048);
72   annot_code_dyn = init_dyn_string(2048, 2048);
73 
74   if (seq->annot_p) {aa1_ann = seq->annot_p->aa1_ann;}
75   else aa1_ann = NULL;
76   loffset = seq->l_offset;
77   l_off = seq->l_off;
78 
79   if (! (*have_ares & 0x1)) {	/* we don't have an a_res, and we need one */
80 
81       my_ares_p = do_walign(aa0, n0, aa1, seq->n1,
82                             frame,
83                             repeat_thresh, ppst, f_str,
84                             have_ares);
85   }
86   else {	/* we already have the a_res */
87       pre_cons(aa1,seq->n1,frame,f_str);
88       my_ares_p = NULL;
89   }
90 
91   /* here, we need to loop through all the alignments, and produce
92      the statistics/codes for each */
93 
94   for (cur_ares_p = my_ares_p; cur_ares_p != NULL; cur_ares_p = cur_ares_p->next) {
95 
96     seqc_max = my_ares_p->nres + 4*m_msp->aln.llen+4;
97     cur_ares_p->aln_code = seq_code = NULL;
98     cur_ares_p->aln_code_n = seq_code_len = 0;
99     cur_ares_p->ann_code = NULL;
100     cur_ares_p->ann_code_n = 0;
101 
102     aln_p = &cur_ares_p->aln;
103 
104     /* this sets a number of constants, from the alignment function
105        and frame, and only needs to be called once */
106     aln_func_vals(frame, aln_p);
107 
108     if ((m_msp->tot_show_code & SHOW_CODE_ALIGN) == SHOW_CODE_ALIGN) {
109       cur_ares_p->aln_code = seq_code=(char *)calloc(seqc_max,sizeof(char));
110       /* if we have an annotation string, allocate space for the
111 	 encoded annotation */
112 
113       if (seq_code != NULL) {
114 
115 	calc_astruct(aln_p, cur_ares_p, f_str);
116 
117 	/* we need this for offset information for calc_code, but it is
118 	 incomplete so we must do it again */
119 
120 	calc_coord(m_msp->n0,seq->n1,
121 		 m_msp->q_offset + (m_msp->q_off-1) + (m_msp->sq0off-1),
122 		 loffset + (l_off-1) + (m_msp->sq1off-1),
123 		 aln_p);
124 
125 	aln_p->lc=calc_code(aa0, m_msp->n0,
126 			    aa1,seq->n1,
127 			    aln_p,cur_ares_p,
128 			    ppst,
129 			    seq_code,seqc_max,
130 			    m_msp->ann_arr,
131 			    m_msp->aa0a, m_msp->annot_p,
132 			    aa1_ann, seq->annot_p,
133 			    annot_code_dyn,
134 			    &score_delta,
135 			    f_str, m_msp->pstat_void,
136 			    m_msp->show_code);
137 
138 	cur_ares_p->aln_code_n = seq_code_len = strlen(seq_code);
139 	if (seq_code[1] == '0' && seq_code[0] == '=') {
140 	  fprintf(stderr," code begins with 0: %s\n", seq_code);
141 	}
142 
143 	if (annot_code_dyn != NULL) {
144 	  ann_code_len = strlen(annot_code_dyn->string);
145 	  cur_ares_p->ann_code = (char *)calloc(ann_code_len+2,sizeof(char));
146 	  SAFE_STRNCPY(cur_ares_p->ann_code,annot_code_dyn->string, ann_code_len+2);
147 	}
148 	else {ann_code_len = 0;}
149 	cur_ares_p->ann_code_n = ann_code_len;
150       }
151     }
152     else {
153       aln_p->lc=calc_id(aa0,m_msp->n0,aa1,seq->n1,
154 			aln_p, cur_ares_p,
155 			ppst,
156 			m_msp->annot_p, seq->annot_p,
157 			&score_delta,
158 			annot_var_dyn, f_str);
159     }
160 
161     if (score_delta > 0) {
162       cur_ares_p->rst.score[0] += score_delta;
163       cur_ares_p->rst.score[1] += score_delta;
164       cur_ares_p->rst.score[2] += score_delta;
165       cur_ares_p->sw_score += score_delta;
166       cur_ares_p->score_delta = score_delta;
167     }
168     else {
169       cur_ares_p->score_delta = 0;
170     }
171 
172     if (annot_var_dyn->string[0] != '\0') {
173       if ((cur_ares_p->annot_var_s = (char *)calloc(strlen(annot_var_dyn->string)+2, sizeof(char)))==NULL) {
174 	fprintf(stderr,"*** ERROR *** [%s/%d] cannot allocate cur_ares_p->annot_var_s [%d]\n",
175 		__FILE__, __LINE__, (int)strlen(annot_var_dyn->string)+2);
176       }
177       else {
178 	strncpy(cur_ares_p->annot_var_s,annot_var_dyn->string,strlen(annot_var_dyn->string)+2);
179       }
180     }
181 
182     /* this should be all the information we need on the alignment */
183   } /* end for (cur_ares_p;) */
184   free_dyn_string(annot_code_dyn);
185   free_dyn_string(annot_var_dyn);
186   return my_ares_p;
187 }
188