1 /*
2  * $Id: vastgraphDB.c,v 1.3 2003/01/14 20:49:20 chenj Exp $
3  *
4  *
5  * ===========================================================================
6  *
7  *                            PUBLIC DOMAIN NOTICE
8  *            National Center for Biotechnology Information (NCBI)
9  *
10  *  This software/database is a "United States Government Work" under the
11  *  terms of the United States Copyright Act.  It was written as part of
12  *  the author's official duties as a United States Government employee and
13  *  thus cannot be copyrighted.  This software/database is freely available
14  *  to the public for use. The National Library of Medicine and the U.S.
15  *  Government do not place any restriction on its use or reproduction.
16  *  We would, however, appreciate having the NCBI and the author cited in
17  *  any work or product based on this material
18  *
19  *  Although all reasonable efforts have been taken to ensure the accuracy
20  *  and reliability of the software and data, the NLM and the U.S.
21  *  Government do not and cannot warrant the performance or results that
22  *  may be obtained by using this software or data. The NLM and the U.S.
23  *  Government disclaim all warranties, express or implied, including
24  *  warranties of performance, merchantability or fitness for any particular
25  *  purpose.
26  *
27  * ===========================================================================
28  *
29  *
30  * Author: Jie Chen
31  *
32  * $Log: vastgraphDB.c,v $
33  * Revision 1.3  2003/01/14 20:49:20  chenj
34  * Imported sources
35  *
36  *
37  * This is to show the "red-cloud" graph.
38  * The footprint alignment is broken at the position of insert.
39  *
40  * ===========================================================================
41 */
42 
43 #include <ncbi.h>
44 #include <ncbistr.h>
45 #include <ncbistd.h>
46 #include <mmdbapi.h>
47 #include <mmdbdata.h>
48 #include <time.h>
49 #include <objgen.h>
50 #include "vastgenDB.h"
51 
52 #define iNcolors 13
53 
54 static double pix_per_res;
55 static CharPtr	QueryBit;
56 static gdImagePtr im;
57 static Int2    white, black, red, blue, gray;
58 static Int4 iDartCol[13];
59 
60 extern Dart_Connect	*dartcon;
61 extern Char URLcgi[MAX_TBUFF],MMDBCGIname[MAX_TBUFF], CGIname[MAX_TBUFF];
62 extern Char MAILto[PATH_MAX],  ENTREZurl[PATH_MAX];
63 extern Char VSPATH[PATH_MAX], CDDurl[PATH_MAX];
64 extern Int4	aSdi;
65 
66 static void
GetLeftAnglePoints(gdPoint * points,Int4 x1,Int4 x2,Int4 dx,Int4 y,Int4 dy)67 GetLeftAnglePoints(gdPoint *points, Int4 x1, Int4 x2, Int4 dx, Int4 y, Int4 dy)
68 {
69         Int4    midp;
70 
71         midp = (x1+x2)/2;
72 
73         points[0].x = MIN(midp, x1+dx); points[0].y = y;
74         points[1].x = x1;               points[1].y = y+0.5*dy;
75         points[2].x = MIN(midp, x1+dx); points[2].y = y+dy;
76 
77 }       /* GetLeftAnglePoints */
78 
79 
80 
81 
82 static void
GetRightAnglePoints(gdPoint * points,Int4 x1,Int4 x2,Int4 dx,Int4 y,Int4 dy)83 GetRightAnglePoints(gdPoint *points, Int4 x1, Int4 x2, Int4 dx, Int4 y, Int4 dy)
84 {
85         Int4 midp;
86 
87         midp = (x2+x1)/2;
88 
89         points[0].x = MAX(midp, x2-dx); points[0].y = y;
90         points[1].x = x2;               points[1].y = y+0.5*dy;
91         points[2].x = MAX(midp, x2-dx); points[2].y = y+dy;
92 
93 }       /* GetRightAnglePoints */
94 
95 
96 
97 
GetPoints(gdPoint * points,Int2 * n,CharPtr flag,Int4 x1,Int4 x2,Int4 y,Int4 dy)98 static void GetPoints(gdPoint *points, Int2 *n, CharPtr flag,
99 			Int4 x1, Int4 x2, Int4 y, Int4 dy)
100 {
101 	Int4 midp, dx;
102 
103 	midp = (x1+x2)/2;
104 
105 	switch (flag[0]) {
106 	case 'L':  	/* Left zigzag */
107                 GetRightAnglePoints(points, x1, x2, 7, y, dy);
108                 points[3].x = x1;               points[3].y = y+dy;
109                 points[4].x = MIN(x1+3, midp);  points[4].y = y+dy*0.75;
110                 points[5].x = x1;               points[5].y = y+dy*0.5;
111                 points[6].x = MIN(x1+3, midp);  points[6].y = y+dy*0.25;
112                 points[7].x = x1;               points[7].y = y;
113                 *n = 8;
114 		break;
115 	case 'R':	/* right zigzag */
116                 GetLeftAnglePoints(points, x1, x2, 7, y, dy);
117                 points[3].x = x2;               points[3].y = y+dy;
118                 points[4].x = MAX(x2-3, midp);  points[4].y = y+dy*0.75;
119                 points[5].x = x2;               points[5].y = y+dy*0.5;
120                 points[6].x = MAX(x2-3, midp);  points[6].y = y+dy*0.25;
121                 points[7].x = x2;               points[7].y = y;
122                 *n = 8;
123 		break;
124 	case 'W':	/* two zigzag lines */
125                 points[0].x = x1;               points[0].y = y;
126                 points[1].x = x2;               points[1].y = y;
127                 points[2].x = MAX(x2-3, midp);  points[2].y = y+dy*0.25;
128                 points[3].x = x2;               points[3].y = y+dy*0.5;
129                 points[4].x = MAX(x2-3, midp);  points[4].y = y+dy*0.75;
130                 points[5].x = x2;               points[5].y = y+dy;
131                 points[6].x = x1;               points[6].y = y+dy;
132                 points[7].x = MIN(x1+3, midp);  points[7].y = y+dy*0.75;
133                 points[8].x = x1;               points[8].y = y+dy*0.5;
134                 points[9].x = MIN(x1+3, midp);  points[9].y = y+dy*0.25;
135                 *n = 10;
136                 break;
137         case 'A':	/* Aligned, so two angles */
138 		if (x2-x1 <=8) dx=3;
139 		else if (x2-x1 <= 18) dx = 4;
140 		else dx = 7;
141 
142                 points[0].x = MIN(midp, x1+dx);  points[0].y = y;
143                 if (x2-x1 < 8) {
144 			points[1].x = x2;  	/* points[1].y = y; */
145 			points[3].x = x2;  	/* points[3].y = y + dy; */
146 		}
147 		else {
148 			points[1].x = MAX(midp, x2-dx);
149 			points[3].x = MAX(midp, x2-dx);
150 		}
151                 points[2].x = x2;                points[2].y = y+0.5*dy;
152                 points[4].x = MIN(midp, x1+dx);  points[4].y = y+dy;
153                 points[5].x = x1;                points[5].y = y+0.5*dy;
154 
155 		points[1].y = y; 		 points[3].y = y+dy;
156 
157                 *n = 6;
158                 break;
159         case 'U':	/* Un...,  special for query */
160                 points[0].x = x1;       points[0].y = y;
161                 points[1].x = x2;       points[1].y = y;
162                 points[2].x = x2;       points[2].y = y+dy;
163                 points[3].x = x1;       points[3].y = y+dy;
164                 *n = 4;
165                 break;
166 	default:
167 		PrtMes(MAILto, "VASTSRV (VastGraph)",
168 		    "Error in GetPoints -- didn't choose points", NULL, FALSE);
169 	}
170 
171 }	/* GetPoints */
172 
173 
174 
175 #define HTMLurl "href=\"%s%s?sdid=%d&viewali=View&action=0&alitype=h"
176 #define VSHTMLurl "href=\"%s%s?chaindom=%d&viewali=View&action=0&alitype=h"
177 
178 static Int4
BlockMapOrImg(Boolean ismap,Int4 x,Int4 y,Int4 x0,Int4 from,Int4 to,Int4 tick_from,Int4 tick_to,Int2 color,Int4 dy,Int4 pre_t,Int4 next_f,Boolean isaligned,Int4 Fsid,VastPageDataPtr vpp,Int4 iSlv,Int4 numhitsdisplayed,CharPtr JobID,CharPtr pcPass,FILE * File)179 BlockMapOrImg(Boolean ismap, Int4 x, Int4 y, Int4 x0, Int4 from, Int4 to,
180 	Int4 tick_from, Int4 tick_to, Int2 color, Int4 dy, Int4 pre_t,
181 	Int4 next_f, Boolean isaligned, Int4 Fsid, VastPageDataPtr vpp,
182 	Int4 iSlv, Int4 numhitsdisplayed, CharPtr JobID, CharPtr pcPass,
183 	FILE *File)
184 {
185   char	altstr[200], str[MAX_TBUFF], str2[20], strnum[MAX_TBUFF];
186   Int2 	i;
187   Int4 	x1=0, x2=0;
188   gdPoint  points[10];
189 
190   CalCoor(&x1, &x2, x, from, to, pix_per_res, MaxSeqImgSize);
191   if (iSlv < 0) if (x1-x0 <2) x1 = x0+2;
192 
193   if (ismap == TRUE) {
194 
195     if (iSlv < 0) {
196     	if (dy==8) sprintf(altstr, "Unaligned residues ");
197     	else sprintf(altstr, "Maximal aligned region: from residues ");
198 	sprintf(str, "%d to %d, ", tick_from, tick_to);
199       	StringCat(altstr, str);
200 	StringCat(altstr,"click for multiple alignment with neighbors.");
201         sprintf(strnum, "%d%%2C", Fsid*10);
202 	for (i=0; i< numhitsdisplayed; i++) {
203             sprintf(str2, "%d%%2C", vpp[i].bBsfId);
204             StringCat(strnum, str2);
205 	}
206     }
207     else {
208 	sprintf(altstr,
209 		"Aligned residues %d to %d, click for sequence alignment.",
210 		tick_from, tick_to);
211     }
212 
213     fprintf(File, "<area shape=rect coords=%d,%d,%d,%d ",
214 		x1, y, x2, y+dy);
215 
216     if (JobID) fprintf(File, VSHTMLurl, URLcgi, CGIname, Fsid);
217     else fprintf(File, HTMLurl, URLcgi, CGIname, aSdi);
218     if (iSlv < 0)  {
219 	fprintf(File, "&nbr_complexity=0&allbsfid=%s", strnum);
220     }
221     else fprintf(File, "&nbr_complexity=1&hit=%d", vpp[iSlv].bBsfId);
222     if (JobID) fprintf(File, "&vsid=%s&pass=%s", JobID, pcPass);
223     fprintf(File, "\"");
224     fprintf(File, " alt=\"%s\" ", altstr);
225     fprintf(File, "ONMOUSEOVER=\"self.status=\'%s\'; return true\">\n", altstr);
226   }
227   else {
228      if (isaligned == TRUE) {
229   	if (!pre_t)  {
230 	    Int2   n;
231 
232 	    if (!next_f) {
233 		GetLeftAnglePoints(points, x1, x2, 7, y, dy);
234 		points[3].x = x2; 	points[3].y = y+dy;
235 		points[4].x = x2; 	points[4].y = y;
236 		n = 5;
237 	    }
238 	    else GetPoints(points, &n, "A", x1, x2, y, dy);
239 
240 	    gdImageFilledPolygon(im, points, n, color);
241 
242 	}
243 	else if (next_f) {
244 		GetRightAnglePoints(points, x1, x2, 7, y, dy);
245 		points[3].x = x1; 	points[3].y = y+dy;
246 		points[4].x = x1; 	points[4].y = y;
247 		gdImageFilledPolygon(im, points, 5, color);
248 	}
249 	else gdImageFilledRectangle(im, x1, y, x2, y+dy, color);
250      }
251      else gdImageFilledRectangle(im, x1, y, x2, y+dy, color);
252   }
253 
254   return(x2);
255 
256 }  /* end of BlockImg */
257 
258 
259 #define EntrezLink "href=\"%s?cmd=Retrieve&db=%s&list_uids=%d&dopt=%s\""
260 
NameMapOrImg(Boolean ismap,Int4 * x,Int4 y,CharPtr pdbname,Char chainname,Int4 iDomain,Int4 iGi,Int4 seqlen,CharPtr pcSlaveName,FILE * File)261 static void NameMapOrImg(Boolean ismap, Int4 *x, Int4 y, CharPtr pdbname,
262 		Char chainname, Int4 iDomain, Int4 iGi, Int4 seqlen,
263 		CharPtr pcSlaveName, FILE *File)
264 {
265 
266   Char 	cTmp[10], str[10], altstr[MAX_TBUFF];
267   Int4	x0;
268 
269   sprintf(cTmp, "%s %c", pdbname, chainname);
270   if (iDomain) {
271 	sprintf(str, " %d", iDomain);
272 	StringCat(cTmp, str);
273   }
274   if (ismap == TRUE) {
275     sprintf(altstr, "%s", pdbname);
276     if (chainname != ' ') {
277 	sprintf(str, "_%c", chainname);
278 	StringCat(altstr, str);
279     }
280     if (iDomain) {
281 		StringCat(altstr, "_");
282 		sprintf(str, "%d", iDomain);
283 		StringCat(altstr, str);
284     }
285     fprintf(File, "<area shape=rect coords=%d,%d,%d,%d ",
286 	    *x, y, *x+StrLen(cTmp)*FontBW, y+FontBH);
287     if (pcSlaveName != NULL) {
288 	sprintf(str, ": %d", seqlen);
289     	StringCat(altstr, str),
290     	StringCat(altstr, " residues");
291         if (!iDomain) StringCat(altstr, ", ");
292 	else {
293 	   if (chainname != ' ') sprintf(str, " on chain %c, ", chainname);
294 	   else sprintf(str, " on chain, ");
295 	   StringCat(altstr, str);
296 	}
297 	StringCat(altstr, pcSlaveName);
298         fprintf(File, "href=\"%s%s?uid=%s", URLcgi, MMDBCGIname, pdbname);
299         fprintf(File, "&form=6&db=t&Dopt=s\" ");
300     }
301     else if (iGi) {
302 	StringCat(altstr, ", click for Entrez sequence summary");
303 	fprintf(File, EntrezLink, ENTREZurl, "protein", iGi, "GenPept");
304     }
305 
306     fprintf(File, "alt=\"%s\" ", altstr);
307     fprintf(File, "ONMOUSEOVER=\"self.status=\'%s\'; return true\">\n",
308 	    altstr);
309   }
310   else {
311     gdImageString(im, gdFont7X13b, *x, y, cTmp, blue);
312     y += FontBH;
313     x0 = *x + StrLen(pdbname)*FontBW;
314     gdImageLine(im, *x, y, x0, y, blue);
315     x0 += FontBW;
316     if (chainname != ' ') gdImageLine(im, x0, y, x0+FontBW, y, blue);
317     x0 += 2*FontBW;
318     if (iDomain) gdImageLine(im, x0, y, x0+FontBW, y, blue);
319   }
320 
321   *x += 11*FontBW;
322 
323 }  /* end NameMapOrImg */
324 
325 
PrintAliMap(Int4 x1,Int4 y1,Int4 x2,Int4 y2,Int4 tick_f,Int4 tick_t,Int4 Fsid,VastPageDataPtr vpp,Int4 iSlv,CharPtr JobID,CharPtr pcPass,FILE * File)326 static void PrintAliMap(Int4 x1, Int4 y1, Int4 x2, Int4 y2, Int4 tick_f,
327 	Int4 tick_t, Int4 Fsid, VastPageDataPtr vpp, Int4 iSlv, CharPtr JobID,
328 	CharPtr pcPass, FILE *File)
329 {
330    char cTmp[MAX_TBUFF], str[100];
331 
332    sprintf(cTmp, "Aligned residues %d to %d, click for sequence alignment",
333 		tick_f, tick_t);
334    fprintf(File, "<area shape=rect coords=%d,%d,%d,%d ",
335 		x1, y1, x2, y2);
336    if (JobID) fprintf(File, VSHTMLurl, URLcgi, CGIname, Fsid);
337    else fprintf(File, HTMLurl, URLcgi, CGIname, aSdi);
338    fprintf(File, "&nbr_complexity=1&hit=%d", vpp[iSlv].bBsfId);
339    if (JobID) fprintf(File, "&vsid=%s&pass=%s", JobID, pcPass);
340    fprintf(File, "\"");
341    fprintf(File, " alt=\"%s\" ", cTmp);
342    fprintf(File, "ONMOUSEOVER=\"self.status=\'%s\'; return true\"", cTmp);
343    fprintf(File, ">\n");
344 }
345 
346 
347 
348 static Int4
InsertOnSlaveMapOrImg(Boolean ismap,Int4 x,Int4 y,Int4 x0,Int4 from,Int4 to,Int4 tick_from,Int4 tick_to,Int4 pre_to,Int4 next_from,IntvlPairDataPtr ipdp,Int4 * segNo,Int4 segNum,Int4 Fsid,VastPageDataPtr vpp,Int4 iSlv,CharPtr JobID,CharPtr pcPass,FILE * File)349 InsertOnSlaveMapOrImg(Boolean ismap, Int4 x, Int4 y, Int4 x0, Int4 from,
350 	Int4 to, Int4 tick_from, Int4 tick_to, Int4 pre_to, Int4 next_from,
351 	IntvlPairDataPtr ipdp, Int4 *segNo,Int4 segNum, Int4 Fsid,
352 	VastPageDataPtr vpp, Int4 iSlv, CharPtr JobID, CharPtr pcPass, FILE *File)
353 {
354   Int2 n=0;
355   Int4 x1, x2, dy,i, idx, next, f_res, t_res;
356   gdPoint points[10];
357 
358   dy = 10;
359   idx = segNo[0];
360   t_res = ipdp[idx-1].mstto;
361   CalCoor(&x1, &x2, x, from, t_res, pix_per_res, MaxSeqImgSize);
362   if (x1-x0 < 2) x1 = x0+2;
363   x2 -= 1.0 + MIN(0, (Int4)(pix_per_res/2.0));
364   if (ismap == TRUE)
365 	PrintAliMap(x1, y, x2, y+dy, tick_from, ipdp[idx-1].slvto,
366 		Fsid, vpp, iSlv, JobID, pcPass, File);
367   else {
368      if (!pre_to) {
369 	Int2 	n;
370 
371 	GetLeftAnglePoints(points, x1, x2, 7, y, dy);
372 	points[3].x = x2;       points[3].y = y+dy;
373         points[4].x = x2;       points[4].y = y;
374         n = 5;
375 
376 	gdImageFilledPolygon(im, points, n, red);
377      }
378      else
379      	gdImageFilledRectangle(im, x1, y, x2, y+dy, red);
380   }
381 
382   for (i=0; i< segNum; i++) {
383     idx = segNo[i];
384     f_res = ipdp[idx].mstfrom;
385     CalCoor(&x1, NULL, x, f_res, 0, pix_per_res, MaxSeqImgSize);
386     x1 += 1.0 + MIN(0, (Int4)(pix_per_res/2.0));
387 /*    if (ismap == FALSE) gdImageFilledRectangle(im, x2, y, x1, y+dy, sky);  */
388     if (i< segNum-1) {
389       next = segNo[i+1];
390       t_res = ipdp[next].mstfrom-1;
391       CalCoor(NULL, &x2, x, 0, t_res, pix_per_res, MaxSeqImgSize);
392       x2 -= 1.0 + MIN(0, (Int4)(pix_per_res/2.0));
393       if (ismap==TRUE)
394 	PrintAliMap(x1, y, x2, y+dy, ipdp[idx].slvfrom, ipdp[next].slvfrom-1,
395 		Fsid, vpp, iSlv, JobID, pcPass, File);
396       else gdImageFilledRectangle(im, x1, y, x2, y+dy, red);
397     }
398   }
399 
400   CalCoor(NULL, &x2, x, 0, to, pix_per_res, MaxSeqImgSize);
401   if (ismap == TRUE) {
402        PrintAliMap(x1, y, x2, y+dy, ipdp[idx].slvfrom, tick_to, Fsid,
403 		vpp, iSlv, JobID, pcPass, File);
404   }
405   else {
406   	if (next_from) {
407   	     GetRightAnglePoints(points, x1, x2, 7, y, dy);
408   	     points[3].x = points[4].x = x1;
409   	     points[3].y = y+dy; points[4].y = y;
410 	     n = 5;
411 	     gdImageFilledPolygon(im, points, 5, red);
412 
413         }
414   	else gdImageFilledRectangle(im, x1, y, x2, y+dy, red);
415   }
416 
417   return(x2);
418 
419 }	/* end InsertOnSlaveMap... */
420 
421 
422 
423 
424 static void
AlignmentMapOrImg(Boolean ismap,Int4 x,Int4 y,Int4 Fsid,Int4 iSlv,Int4 seqlen_s,VastPageDataPtr vpp,CharPtr stats,Int2 sortnamelen,CharPtr JobID,CharPtr pcPass,FILE * File)425 AlignmentMapOrImg(Boolean ismap, Int4 x, Int4 y, Int4 Fsid, Int4 iSlv,
426 	Int4 seqlen_s, VastPageDataPtr vpp, CharPtr stats, Int2 sortnamelen,
427 	CharPtr JobID, CharPtr pcPass, FILE *File)
428 {
429   char		pdbId_s[5], chnLett_s;
430   CharPtr	pcSlaveName = NULL;
431   Int2		i, j;
432   Int4		x0=-1, dy, from_m,from_s;
433   Int4		to_m, to_s, ali_from_m, ali_to_m=0, ali_from_s=0;
434   Int4		ali_to_s=-1, pre_to_s=0, segNo[20];
435   Int4		segNum = 0, domNo_s;
436   IntvlPairData	*ipdp;
437 
438   dy = 10;
439 
440   if (ismap == TRUE) {
441       pcSlaveName = (CharPtr) MemNew ((size_t)(2*DBStrSize+4));
442       pcSlaveName[0] = '\0';
443       if(vpp[iSlv].name[0] != '\0' || vpp[iSlv].name2[0] != '\0') {
444           if(vpp[iSlv].name[0] != '\0')
445                 strcpy(pcSlaveName,vpp[iSlv].name);
446           if(vpp[iSlv].name2[0] != '\0')
447                 strcat(pcSlaveName,vpp[iSlv].name2);
448       }
449   }
450 
451   StrCut(pdbId_s, vpp[iSlv].bDomName, 1, 4);
452   chnLett_s = (vpp[iSlv].bDomName)[4];
453   domNo_s = (Int4)atoi(vpp[iSlv].bDomName+5);
454   ipdp = vpp[iSlv].Ipdp;
455 
456   NameMapOrImg(ismap, &x, y, pdbId_s, chnLett_s, domNo_s, 0, seqlen_s,
457 		pcSlaveName, File);
458 
459   if (ismap==TRUE) MemFree(pcSlaveName);
460 
461   for (i = 0; i< vpp[iSlv].IpdpLen; i++) {
462     from_m = ipdp[i].mstfrom;
463     to_m = ipdp[i].mstto;
464     from_s = ipdp[i].slvfrom;
465     to_s = ipdp[i].slvto;
466 
467 /*  red piece for aligned region */
468     if (!i) {
469 	ali_from_m = from_m;
470 	ali_from_s = from_s;
471     }
472 
473 
474     if (i && from_m == ali_to_m+1) {
475 		if (from_s > ali_to_s+1) segNo[segNum++] = i;
476     }
477     else {
478   	if (i) {
479 
480 	   if (!segNum)
481 	 	x0 = BlockMapOrImg(ismap, x, y, x0, ali_from_m, ali_to_m,
482 			ali_from_s, ali_to_s, red, dy, pre_to_s, 0, TRUE, Fsid,
483 			vpp, iSlv, 0, JobID, pcPass, File);
484 	   else
485 		x0 = InsertOnSlaveMapOrImg(ismap, x, y, x0, ali_from_m,
486 			ali_to_m, ali_from_s, ali_to_s, pre_to_s, 0, ipdp,
487 			segNo, segNum, Fsid, vpp, iSlv, JobID, pcPass, File);
488 
489 	   for (j = ali_from_m-1; j< ali_to_m; j++) QueryBit[j] = '1';
490 
491       	   if (!pre_to_s) pre_to_s = ali_to_s;
492       	}
493 
494 
495       ali_from_m = from_m;
496       ali_from_s = from_s;
497       segNum = 0;
498     }
499 
500     ali_to_m = to_m;
501     ali_to_s = to_s;
502 
503   }	/* for (i = 0 ... */
504 
505 
506 /* rectangle with red color from from_m to to_m ----  aligned block */
507 
508   if (!segNum)
509   	x0 =BlockMapOrImg(ismap, x, y, x0, ali_from_m, ali_to_m, ali_from_s,
510 		ali_to_s, red, dy, pre_to_s, 1, TRUE, Fsid, vpp, iSlv, 0,
511 		JobID, pcPass, File);
512   else
513 	x0 = InsertOnSlaveMapOrImg(ismap, x, y, x0, ali_from_m, ali_to_m,
514 		ali_from_s, ali_to_s, pre_to_s, 1, ipdp, segNo, segNum,
515 		Fsid, vpp, iSlv, JobID, pcPass, File);
516 
517   for (j = ali_from_m-1; j< ali_to_m; j++) QueryBit[j] = '1';
518 
519 /* print stats */
520 
521   x =GraphWidth - (MAX(sortnamelen, StrLen(stats)) + StrLen(stats))*FontBW/2.0;
522   if (ismap==FALSE)
523 	gdImageString(im, gdFont7X13b, x, y, stats, blue);
524 
525 } /* end of AlignImg() */
526 
527 
528 
529 
530 static void
GetLeft4Points(Int4 x1,Int4 x2,Int4 y1,Int4 y2,gdPointPtr points)531 GetLeft4Points(Int4 x1, Int4 x2, Int4 y1, Int4 y2, gdPointPtr points)
532 {
533 	Int4 i=0;
534 
535 	points[i].x = x2; 	points[i++].y = y1;
536 	points[i].x = x1; 	points[i++].y = y1+2;
537 	points[i].x = x1; 	points[i++].y = y2-2;
538 	points[i].x = x2; 	points[i++].y = y2;
539 
540 }
541 
542 
543 
544 
545 static void
GetRight4Points(Int4 x1,Int4 x2,Int4 y1,Int4 y2,gdPointPtr points)546 GetRight4Points(Int4 x1, Int4 x2, Int4 y1, Int4 y2, gdPointPtr points)
547 {
548 	Int4 i=0;
549 
550 	points[i].x = x1; 	points[i++].y = y2;
551 	points[i].x = x2; 	points[i++].y = y2-2;
552 	points[i].x = x2; 	points[i++].y = y1+2;
553 	points[i].x = x1; 	points[i++].y = y1;
554 }
555 
556 
557 #define CDDsrv "href=\"%s?ascbin=2&maxaln=10&seltype=3&uid=%s&aln=%s&querygi=%d&querynm=%s&version=%s\""
558 #define CDDOpt "db=cdd&term="
559 #define DomOpt "db=structure&cmd=Display&dopt=structure_domains&from_uid="
560 
561 
QueryMapOrImg(Boolean ismap,Int4 x,Int4 y,CharPtr pcPDB,Int4 iMMDBid,Int4 Fsid,Char cChain,Int4 domNo,Int4 gi,Int4 seqlen,DomIntvlDataPtr dip,Int4 domintvl_no,VastPageDataPtr vpp,Int4 numhitsdisplayed,CharPtr JobID,CharPtr pcPass,FILE * File)562 static void QueryMapOrImg(Boolean ismap, Int4 x, Int4 y, CharPtr pcPDB,
563 		Int4 iMMDBid, Int4 Fsid, Char cChain, Int4 domNo, Int4 gi,
564 		Int4 seqlen, DomIntvlDataPtr dip, Int4 domintvl_no, VastPageDataPtr vpp,
565 		Int4 numhitsdisplayed, CharPtr JobID, CharPtr pcPass,FILE *File)
566 {
567   char		cTmp[MAX_TBUFF], shortname[MAX_TBUFF], str[MAX_TBUFF];
568   char		defline[MAX_TBUFF], def2[MAX_TBUFF], *chtmp;
569   char		cdalign[MAX_TBUFF], querynm[MAX_TBUFF];
570   char		definition[MAX_TBUFF];
571   CharPtr	*CddName;
572   DenseSegPtr	*dsp;
573   Int2 		i, color, char_num;
574   Int4 		alinumseg,j, x0=-1,y0, x1, x2, y1, y2, len, dont, x_ori, numseg;
575   Int4Ptr	starts, lens;
576   Int4 		index, ntick, tick, right, dy=0, from, to, len1, len2, minali;
577   OverLoc	*head, *end;
578   SeqAnnotPtr	sap = NULL;
579   SeqAlignPtr	salp= NULL;
580   static Int4 	ticksteps[9] = {5, 10, 20, 25, 50, 100, 200, 150, 500};
581 
582   x_ori = x;
583 
584   NameMapOrImg(ismap, &x, y, pcPDB, cChain, 0, gi, seqlen, NULL, File);
585 
586   y1 = y+3;
587 
588 /* sequence ruler */
589 
590   j = minali = 0;
591   while (j < seqlen) {
592      char  	bitj;
593      Int4 	color, k, l, dy, pre_t, next_f, y0;
594      Boolean	aliflag;
595 
596      bitj = QueryBit[j];
597      switch (bitj) {
598 	case '0': color=gray; aliflag = FALSE; dy = 8;
599 		  pre_t = next_f = 1; y0 = y1;
600 		  break;
601 	case '1': color = red; aliflag = TRUE; dy = 14;
602 		  if (!minali) {
603 			minali = 1; pre_t = 0;
604 		  }
605 		  else pre_t = 1;
606 		  y0 = y;
607 		  break;
608      }
609 
610      k = j+1;
611      while (k< seqlen && bitj == QueryBit[k]) k++;
612 
613      if (bitj == '1') {
614 	l = k+2;
615      	while (l< seqlen && QueryBit[l] != bitj) l++;
616      	if (l >= seqlen) next_f = 1;
617  	else next_f = 0;
618      }
619 
620      x0 = BlockMapOrImg(ismap, x, y0, x0, ++j, k, j, k, color, dy, pre_t,
621 		next_f, aliflag, Fsid, vpp, -1, numhitsdisplayed, JobID,
622 		pcPass, File);
623      j = k;
624   }
625 
626 
627   if (ismap == FALSE) {
628 
629     /* Add ticks */
630 
631     CalCoor(NULL, &right, x, 0, seqlen, pix_per_res, MaxSeqImgSize);
632 
633     y2 = y-5;
634     if (QueryBit[0] == '1') gdImageLine(im, x, y, x, y2, red);
635     else  gdImageLine(im, x, y1, x, y2, red);
636     if (QueryBit[seqlen-1] == '1') gdImageLine(im, right, y, right, y2, red);
637     else gdImageLine(im, right, y1, right, y2, red);
638 
639     y2 -= FontMH;
640 
641     gdImageString(im, gdFont6X12, x, y2, "1", red);
642     sprintf(cTmp, "%d", seqlen);
643     gdImageString(im, gdFont6X12, right-(StrLen(cTmp)-1)*FontMW, y2, cTmp, red);
644 
645     y2 += FontMH;
646 
647     for (i=0; i< 9; i++) {
648       ntick = seqlen/ticksteps[i];
649       if (ntick < 10) {
650 	tick = ticksteps[i];
651 	break;
652       }
653     }
654 
655     x0 = x + 2*FontMW;
656     dont = right - StrLen(cTmp)*FontMW;
657     for (i=1; i<=ntick; i++){
658       x1 = (Int4)(x+(float)(i*tick-1) * pix_per_res);
659       if (x1 > dont) continue;
660 
661       if (QueryBit[i*tick-1] == '1') gdImageLine(im, x1, y, x1, y2, red);
662       else gdImageLine(im, x1, y1, x1, y2, red);
663 
664       sprintf(cTmp, "%d", i*tick);
665       len = StrLen(cTmp)*FontMW/2;
666       x2 = x1 + len;
667       x1 -= len;
668       if (x2<dont && (x2-x0 > len)) {
669 	gdImageString(im, gdFont6X12, x1, y2-FontMH, cTmp, red);
670 	x0 = x2 + FontMW;
671       }
672     }
673   }
674 
675 /* "3d Domains" & "CDs" */
676 
677   if (!gi) return;
678 
679   if (domintvl_no > 1) {
680     x = x_ori;  y += FontBH+5;
681 
682     if (ismap == FALSE)
683 	NameMapOrImg(ismap, &x, y, "3d Dom.", ' ', 0, 0, 0, NULL, NULL);
684     else {
685 	fprintf(File, "<area shape=rect coords=%d,%d,%d,%d ",
686 		x, y, x+StrLen("3d Dom.")*FontBW, y+FontBH);
687 	sprintf(cTmp, "Click for Entrez 3d Domains");
688 	fprintf(File, "href=\"%s?%s%d\" alt=\"%s\" ",
689 			ENTREZurl, DomOpt, iMMDBid, cTmp);
690 	fprintf(File,"ONMOUSEOVER=\"self.status=\'%s\'; return true\">\n",cTmp);
691 	x += 11*FontBW;
692     }
693 
694     if (!domNo) domintvl_no = 1;
695     for (i = 0; i< domintvl_no; i++) {
696 
697       if (domNo && !dip[i].domNo) continue;
698 
699       y2 = y+FontBH+2;
700       if (dip[i].domNo != domNo) {
701 	if (ismap == FALSE) color = gray;
702 	y1 = y+1;
703 	y2 -= 2;
704       }
705       else {
706 	if (ismap == FALSE) color = red;
707 	y1 = y;
708       }
709 
710       CalCoor(&x1, &x2, x, dip[i].frm, dip[i].tu, pix_per_res, MaxSeqImgSize);
711       if (ismap == TRUE) {
712 
713 	  sprintf(cTmp, "Residue %d to %d", dip[i].frm, dip[i].tu);
714 	  StringCat(cTmp, ", click for structure neighbors");
715 
716 	  fprintf(File, "<area shape=rect coords=%d,%d,%d,%d ",
717 		  x1, y1, x2, y2);
718 	  if (JobID) {
719 		fprintf(File, "href=\"%s%s?chaindom=%d", URLcgi, CGIname,
720 			(Fsid+(dip[i].domNo - domNo)));
721 	  }
722 	  else 	{
723 		fprintf(File, "href=\"%s%s?sdid=%d", URLcgi, CGIname,
724 			LongDomIdToSdi(Fsid +(dip[i].domNo - domNo)));
725 	  }
726 	  fprintf(File, "&form=6&db=t&Dopt=s\" alt=\"%s\" ", cTmp);
727 	  fprintf(File, "ONMOUSEOVER=\"self.status=\'%s\'; return true\">\n",
728 		  cTmp);
729       }
730       else {
731 	  gdPoint points[10];
732 	  Int2	  n;
733 
734 	  if (dip[i].domNo != domNo) {
735 	     if (dip[i].frm == 1) {
736 		points[0].x = x1;   	points[0].y = y1;
737 		points[1].x = x1;	points[1].y = y2;
738 		n = 2;
739 	     }
740 	     else {
741 		GetLeft4Points(x1, MIN((x1+x2)/2, x1+2), y1, y2,points);
742 		n = 4;
743 	     }
744 
745 	     if (dip[i].tu == seqlen) {
746 		points[n].x = x2;	points[n++].y = y2;
747 		points[n].x = x2;	points[n++].y = y1;
748 	     }
749 	     else {
750 		GetRight4Points(MAX((x1+x2)/2, x2-2), x2, y1, y2, points+n);
751 		n += 4;
752 	     }
753 	     gdImageFilledPolygon(im, points, n, color);
754 	  }
755 	  else
756 	  	gdImageFilledRectangle(im, x1, y1, x2, y2-2, color);
757 
758 	  if (dip[i].domNo) sprintf(cTmp, "%d", dip[i].domNo);
759 	  else sprintf(cTmp, "Chain %c", cChain);
760 	  if (x2-x1>StrLen(cTmp)*FontBW) {
761 	    x0 = (x1+x2-StrLen(cTmp)*FontBW)/2.0;
762 	    gdImageString(im, gdFont7X13b, x0, y+1, cTmp, white);
763 	  }
764       }
765 
766     } /* for (i=0; i< domintvl_no  */
767   }
768 
769   cTmp[0] = '\0';
770 
771   if (Dart_Gi2Sap(dartcon, gi, &sap, NULL)  && (sap != NULL)) {
772 
773     unsigned	*Pssmlist, *PssmId, count;
774     Int2	*iColor, CdNum, thisColor=0, *iClus;
775     Int4	NumRows;
776 
777     Char CDDdb[1024], Version[1024];
778     Dart_Version(dartcon, CDDdb, 100, Version, 1024);
779     if (StrLen(CDDdb))
780     	StrCut(Version, Version, StrLen(CDDdb)+2, StrLen(Version));
781 
782     if (!Dart_CdNum(dartcon, &count))
783             PrtMes("chenj@ncbi.nlm.nih.gov",
784                         "MmdbSrv", "Can't do Dart_CdNum()", NULL, FALSE);
785     Pssmlist = (unsigned *) MemNew (count * sizeof (unsigned));
786 
787     end = head = NewOverLoc(seqlen);
788     head->y = y0 = y+7+FontBH;
789     head->next = NULL;
790 
791     for (salp = (SeqAlignPtr)sap->data, CdNum=0; salp!=NULL;
792 		salp=salp->next, CdNum++);
793 
794     iColor = (Int2Ptr) MemNew (CdNum * sizeof(Int2));
795     PssmId = (unsigned *) MemNew (CdNum * sizeof(unsigned));
796     dsp = (DenseSegPtr *) MemNew (CdNum * sizeof(DenseSegPtr));
797     CddName = (CharPtr *) MemNew (CdNum * sizeof(CharPtr));
798     for (j=0; j< CdNum; j++) CddName[j] = (CharPtr) MemNew (30);
799     iClus = (Int2Ptr) MemNew (CdNum * sizeof(Int2));
800 
801     for (salp = (SeqAlignPtr)sap->data, i=0; salp!=NULL; salp=salp->next, i++) {
802       dsp[i] = (DenseSegPtr)salp->segs;
803       PssmId[i] = GetPSSMID(dsp[i]);
804       iClus[i] = -1;
805 
806       if (PssmId[i])
807       	Dart_CDGi2Acc(dartcon, PssmId[i], CddName[i], 30);
808       else {
809 	CharPtr strtmp;
810 
811 	strtmp = GetCDDName(dsp[i]);
812 	sprintf(CddName[i], strtmp);
813       }
814 
815     }
816 
817 
818     for (i=0; i< CdNum; i++) {
819 
820 	if (iClus[i] >= 0) continue;
821 
822 	if (ismap == FALSE) iColor[i] = (thisColor++) % iNcolors;
823 	iClus[i] = i;
824 
825 	if (Dart_Related(dartcon, CddName[i],Pssmlist,count,&NumRows, NULL)) {
826 
827           Int2 k;
828 
829 	  if (NumRows > count)
830              PrtMes("chenj@ncbi.nlm.nih.gov", "VASTSRV",
831                 "Dart_Related(): NumRows>MaxPssm", NULL, FALSE);
832 
833 	  for (j=0; j< NumRows; j++) {
834 	    for (k=i+1; k< CdNum; k++)
835 	      if (PssmId[k] == Pssmlist[j]) {
836 		    if (ismap == FALSE) iColor[k] = iColor[i];
837 		    iClus[k] = i;
838 	 	}
839 	  }
840 	}
841     }
842 
843 
844     sprintf(querynm, "%s%c(query)", pcPDB, cChain);
845     for (i=0; i< StrLen(querynm); i++)
846              if (isalpha(querynm[i])) querynm[i] = tolower(querynm[i]);
847     if (querynm[4] == ' ') querynm[4] = '+';
848 
849     for (i=0; i< CdNum; i++) {
850 
851       numseg = (dsp[i])->numseg;
852       starts = (dsp[i])->starts;
853       lens = (dsp[i])->lens;
854       from  = starts[0] + 1;
855       to = starts[(numseg-1)*2] + lens[numseg-1];
856 
857       CalCoor(&x1, &x2, x, from, to, pix_per_res, MaxSeqImgSize);
858       y = GetY1(head, &end, from, to, seqlen, iClus[i], 5);
859       if (y < 0) continue;
860       y2 = y+FontBH+2;
861 
862       Dart_Acc2Info(dartcon, CddName[i], shortname, MAX_TBUFF, defline,
863 		    MAX_TBUFF, definition, MAX_TBUFF);
864 
865       if (ismap == TRUE) {
866 	if (StrLen(defline) == 254) strcpy((defline+StrLen(defline)-3), "...");
867 	if (defline[StrLen(defline)-1] != '.') StringCat(defline, ".");
868 
869 	chtmp = strchr(defline, ';');
870 	sprintf(str, "%s:", CddName[i]);
871 	sprintf(def2, defline);
872 	if (chtmp) {
873 	    strncpy(def2, def2, (chtmp-defline-1));
874 	    def2[chtmp-defline]='.';
875             def2[chtmp-defline+1]='\0';
876 	}
877         else {
878             chtmp = strchr(defline, '.');
879             if (chtmp) {
880             	strncpy(def2, def2, (chtmp-defline));
881                 def2[chtmp-defline+1]='\0';
882             }
883             else
884                 StringCat(def2, ".");
885         }
886         StringCat(str, def2);
887         StringCat(str, " Click for the CD alignment.");
888         strcpy(def2, str);
889 
890 	alinumseg = 0;
891 	cdalign[0] = '\0';
892 	for (j=0; j< numseg; j++) {
893              index = 2*j;
894              if (starts[index]!= -1 && starts[index+1] != -1) {
895 		 sprintf(str, ",%d,%d,%d", starts[index+1], starts[index],
896 				lens[j]);
897 		 StringCat(cdalign, str);
898                  alinumseg++;
899               }
900         }
901         sprintf(str, "%d", alinumseg);
902         StringCat(str, cdalign);
903 
904 	fprintf(File, "<area shape=rect coords=%d,%d,%d,%d ",
905 		x1, y, x2, y2);
906 	fprintf(File, CDDsrv, CDDurl, CddName[i], str, gi, querynm, Version);
907 	fprintf(File, "alt=\"%s: %s %s\" ", CddName[i], defline,
908 			"Click for CD alignment");
909 	fprintf(File, "ONMOUSEOVER=\"self.status=\'%s\'; return true\">\n",
910 		def2);
911 
912         StringCat(cTmp, "+OR+");
913         StringCat(cTmp, CddName[i]);
914         StringCat(cTmp, "[ACCN]");
915 
916       }
917       else {  	/* ismap == FALSE */
918 
919 	gdImageRoundRectangle(im, x1, y, x2, y2, 8, 5,
920 		iDartCol[iColor[i]], 1);
921 
922 	len1 = StrLen(shortname)*FontBW;
923 	len2 = StrLen(shortname)*FontMW;
924 	color = white;
925 	if (iColor[i] == 2 || iColor[i] == 4 || iColor[i] == 0) color=black;
926 	if ((x2-x1)> len1)
927 		gdImageString(im, gdFont7X13b, (x1+x2-len1)/2, y+1,
928 				shortname, color);
929 	else if ((x2-x1) > len2)
930 		gdImageString(im, gdFont6X12, (x1+x2-len2)/2, y+1,
931 			      shortname, color);
932 	else {
933 		char_num = (x2-x1)/FontBW;
934 	         if (char_num >= 3) strcpy(&(shortname[char_num-3]), "...");
935          	else switch (char_num) {
936                 	case 1: strcpy(shortname, "."); break;
937                 	case 2: strcpy(shortname, "..");
938               	}
939 	  	gdImageString(im, gdFont7X13b, x1+2, y+1, shortname, color);
940 	}
941       }
942 
943       if (!dy) {
944 	dy = y0-y;
945 	y0 = y;
946       }
947     }
948 
949     if (!dy) dy=4;
950     else dy = 10;
951 
952     x = x_ori;
953     if (ismap == FALSE)
954       NameMapOrImg(ismap, &x, head->y+2, "CDs", ' ', 0, 0, 0, NULL, NULL);
955     else {
956 	sprintf(str, "Click for Entrez Conserved Domains.");
957 	fprintf(File, "<area shape=rect coords=%d,%d,%d,%d ",
958 		x, head->y+dy, x+StrLen("CDs")*FontBW, head->y+dy+FontBH);
959 	fprintf(File, "href=\"%s?%s%s\" alt=\"%s\" ",
960 			ENTREZurl, CDDOpt, cTmp+4, str);
961 	fprintf(File, "ONMOUSEOVER=\"self.status=\'%s\'; return true\">\n",str);
962     }
963 
964 
965     FreeOverLoc(head);
966     MemFree(iColor);
967     MemFree(PssmId);
968     MemFree(dsp);
969     for (i=0; i< CdNum; i++) MemFree(CddName[i]);
970     MemFree(CddName);
971     MemFree(iClus);
972     MemFree(Pssmlist);
973   }
974 
975 } /* end of QueryMapOrImg */
976 
977 
978 #define MaxDipLen 120
979 
ImgMapOrDraw(Boolean ismap,Int4 Fsid,VastPageDataPtr vpp,Int4 numhitsdisplayed,Int4 iKept,CharPtr selnbrstring,CharPtr selsdidstring,SortBy sortby,SubSetID subsetnum,Int4 pagenum,Int4 StartLoc,CharPtr JobID,CharPtr pcPass,FILE * File)980 void ImgMapOrDraw(Boolean ismap, Int4 Fsid, VastPageDataPtr vpp,
981 	Int4 numhitsdisplayed, Int4 iKept, CharPtr selnbrstring,
982 	CharPtr selsdidstring, SortBy sortby,
983 	SubSetID subsetnum, Int4 pagenum, Int4 StartLoc, CharPtr JobID,
984 	CharPtr pcPass, FILE *File)
985 {
986   char          stats[100], str[100], a_pdbId[5];
987   char		a_chainLett;
988   DomIntvlData	dip[MaxDipLen];
989   float         f;
990   Int4          i, a_MMDBid, a_chainid, a_domNo, a_gi=0, a_seqlen, b_seqlen;
991   Int4		b_MMDBid, b_chainid;
992   Int4          x, y, a_domintvl_no=0;
993   static char SortBy_name[6][10] ={"Ali_Len", "Score", "P_value",
994                                 "Rmsd", "Ali_Res.", "%Id."};
995   static char altstr[6][100]={"Number of Aligned Residues",
996 				"Vast Score",
997 				"Vast P_value",
998 				"Room-mean square deviation",
999                                 "Number of Aligned Residues",
1000 				"Identity"};
1001 
1002   a_MMDBid = Fsid/10000;
1003   a_chainid = (Fsid % 10000) / 100;
1004 
1005   StrCut(a_pdbId, vpp[0].aDomName, 1, 4);
1006   a_chainLett = vpp[0].aDomName[4];
1007   a_domNo = (Int4) atol(vpp[0].aDomName+5);
1008 
1009   if (!JobID) {
1010   	a_domintvl_no =
1011 	    constructDomIntvlData(a_MMDBid, a_chainid, dip, MaxDipLen);
1012 
1013   	a_seqlen = dip[0].tu;
1014   	a_gi = constructGi(a_MMDBid, a_chainid);
1015   }
1016   else {
1017 	AsnIoPtr		aipr=NULL;
1018 	BiostrucPtr		a_bstp = NULL;
1019         BioseqPtr		bsqp = NULL;
1020 	BioseqSetPtr		bssp = NULL;
1021 	BiostrucResidueGraphSetPtr    stdDictionary;
1022         Char 			AsnPath[MAX_TBUFF], str[10];
1023 	ObjectIdPtr		objidp = NULL;
1024 	SeqEntryPtr		sep = NULL;
1025  	SeqIdPtr		sip = NULL;
1026 
1027 	sprintf(AsnPath, VSPATH);
1028 	StringCat(AsnPath, JobID);
1029 	StringCat(AsnPath, "/b");
1030 	StringCat(AsnPath, a_pdbId);
1031 
1032 	a_bstp = FetchBS(AsnPath, 0, ONECOORDRES, 1, POWER_VIEW);
1033 
1034 	aipr = AsnIoOpen("bstdt", "rb");
1035 	stdDictionary = BiostrucResidueGraphSetAsnRead(aipr, NULL);
1036 	AsnIoFlush(aipr);
1037     	aipr = AsnIoClose(aipr);
1038 
1039 	sep = (SeqEntryPtr) MakeBioseqs(a_bstp, stdDictionary);
1040 
1041 	if (!sep)
1042 	     PrtMes(MAILto, "VASTSRV (VastGraph, VS1)",
1043 			"Unable to get SeqEntry", NULL, FALSE);
1044 
1045 	if (sep->choice == 2){
1046 	   Int2 i=1;
1047 
1048 	   bssp = (BioseqSetPtr)sep->data.ptrvalue;
1049 	   sep  = (SeqEntryPtr) bssp->seq_set;
1050 	   while (i< a_chainid) {
1051 		sep = sep->next;
1052 		i++;
1053 	   }
1054 	   if (!sep)
1055 		PrtMes(MAILto, "VASTSRV (VastGraph, VS2)",
1056                         "Unable to get SeqEntry", NULL, FALSE);
1057 
1058 	}
1059  	bsqp = (BioseqPtr)sep->data.ptrvalue;
1060 	sip = bsqp->id;
1061 	while (sip) {
1062 	     if (sip->choice == SEQID_LOCAL) {
1063 	     	sprintf(str, "%s %c %d", a_pdbId, a_chainLett, a_domNo);
1064 	     	objidp = (ObjectIdPtr)sip->data.ptrvalue;
1065 	        if (!StringNCmp(objidp->str, str, 6)) {
1066 		    a_seqlen = bsqp->length;
1067 		    break;
1068 	      	}
1069 	     }
1070    	     sip = sip->next;
1071 	}
1072 
1073 	BiostrucFree(a_bstp);
1074   }
1075 
1076   pix_per_res= (float)MaxSeqImgSize/(float)a_seqlen;
1077   QueryBit = (CharPtr) MemNew ((size_t)(a_seqlen+1));
1078   for (i=0; i< a_seqlen; i++) QueryBit[i] = '0';
1079 
1080   y = StartLoc+3;
1081 
1082   x = GraphWidth - StrLen(SortBy_name[sortby])*FontBW;
1083   if (ismap == TRUE) {
1084 
1085     sprintf(str, "%s. Click for a printable table.", altstr[sortby]);
1086 
1087     fprintf(File, "<area shape=rect coords=%d,%d,%d,%d ",
1088 	     x, 25, GraphWidth, 25+FontBH);
1089     fprintf(File, "href=");
1090     if (JobID) fprintf(File, VSParURL, URLcgi, CGIname, Fsid, sortby);
1091     else fprintf(File, ParURL, URLcgi, CGIname, aSdi, sortby);
1092     if (selnbrstring == NULL && selsdidstring == NULL) {
1093 	if (pagenum)
1094             fprintf(File, PageSubsetURL, pagenum, subsetnum, subsetnum);
1095 	else fprintf(File, "schsub=Find");
1096     }
1097     else {
1098 	fprintf(File, "schsub=Find");
1099 	if (selnbrstring) fprintf(File, "&selnbr=%s", selnbrstring);
1100 	if (selsdidstring) fprintf(File, "&selsdid=%s", selsdidstring);
1101     }
1102 
1103     if (iKept)
1104       	for (i=0; i< iKept; i++)
1105        		fprintf(File, "&hit=%d", vpp[i].bBsfId);
1106     if (JobID) fprintf(File, "&vsid=%s&pass=%s", JobID, pcPass);
1107     fprintf(File, "&table=y\" alt=\"%s\" ", str);
1108     fprintf(File, "ONMOUSEOVER=\"self.status=\'%s\'; return true\">\n", str);
1109   }
1110   else
1111 	NameMapOrImg(ismap, &x, 25, SortBy_name[sortby], ' ', 0, 0, 0,
1112 			NULL, NULL);
1113 
1114   x = 10;
1115   for (i=0; i< numhitsdisplayed; i++) {
1116 
1117       b_MMDBid = vpp[i].bBsfId / 100000;
1118       b_chainid = (vpp[i].bBsfId % 100000) / 1000;
1119       b_seqlen = constructChainLength(b_MMDBid, b_chainid);
1120 
1121       if (!sortby || sortby==4) sprintf(stats, "%d", vpp[i].nres);
1122       else {
1123 	if (sortby == 1) f = (float) vpp[i].vScore;
1124 	else if (sortby == 2)f = (float) vpp[i].mlogp;
1125 	else if (sortby == 3) f = (float) vpp[i].rmsd;
1126 	else f = (float) vpp[i].pcntId;
1127 	f /= (float) ASP_SCALE_FACTOR;
1128 	if (sortby == 1 || sortby == 3) sprintf(stats, "%.1f", f);
1129 	else if (sortby == 5)sprintf(stats, "%.1f", f*100.0);
1130 	else {
1131 
1132           /* adjust for database size */
1133 	  f -= LOG10_500;
1134 	  if (f <= 4.0) {
1135 	    f = (float) exp(-LOG_10*f);
1136 	    sprintf(stats, "%.4f", f);
1137 	  }
1138 	  else sprintf(stats, "10e-%.1f", f);
1139 	}
1140       }
1141 
1142     AlignmentMapOrImg(ismap, x, y, Fsid, i, b_seqlen, vpp, stats,
1143 		StrLen(SortBy_name[sortby]), JobID, pcPass, File);
1144     y += 30;
1145 
1146   }
1147 
1148   /* draw query domain as a ruller */
1149 
1150   y = 30;
1151   QueryMapOrImg(ismap, x, y, a_pdbId, a_MMDBid, Fsid, a_chainLett, a_domNo,
1152 		a_gi, a_seqlen, dip, a_domintvl_no, vpp, numhitsdisplayed,
1153 		JobID, pcPass, File);
1154 
1155 }  /* ImgMapOrDraw */
1156 
1157 
1158 
DrawStrucNbr(Int4 Fsid,VastPageDataPtr vpp,Int4 numhitsdisplayed,Int4 iKept,CharPtr selnbrstring,CharPtr selsdidstring,SortBy sortby,SubSetID subsetnum,Int4 pagenum,Int2 ImageSize,CharPtr JobID,CharPtr pcPass)1159 void DrawStrucNbr(Int4 Fsid, VastPageDataPtr vpp, Int4 numhitsdisplayed,
1160 		Int4 iKept, CharPtr selnbrstring, CharPtr selsdidstring,
1161 		SortBy sortby,
1162 		SubSetID subsetnum, Int4 pagenum, Int2 ImageSize,
1163 		CharPtr JobID, CharPtr pcPass)
1164 {
1165 
1166 	Int4 StartLoc;
1167 
1168 	printf("Content-type: image/gif\n\n");
1169 	im = gdImageCreate(GraphWidth, ImageSize);
1170 	white   = gdImageColorAllocate(im, 255, 255, 255);
1171 	black   = gdImageColorAllocate(im,   0,   0,   0);
1172         blue    = gdImageColorAllocate(im, 0, 0, 255);
1173 	red     = gdImageColorAllocate(im, 255, 0, 0);
1174         /* magenta = gdImageColorAllocate(im, 255, 0, 255); */
1175         gray 	= gdImageColorAllocate(im, 102, 102, 102);
1176 
1177 /* Dart Color scheme */
1178 	iDartCol[5]  = red;
1179 	iDartCol[1]  = blue;
1180 	iDartCol[2]  = gdImageColorAllocate(im, 0, 255, 0);   /* green */
1181 	iDartCol[3]  = gdImageColorAllocate(im, 204,102,  0); /* orange */
1182 	iDartCol[4]  = gdImageColorAllocate(im, 204,204,  0); /* yeller */
1183 	iDartCol[0]  = gdImageColorAllocate(im, 153,204,255); /* sky b */
1184 	iDartCol[6]  = gdImageColorAllocate(im, 102,153,  0); /* spring */
1185 	iDartCol[7]  = gdImageColorAllocate(im, 204,102,153); /* lavender */
1186 	iDartCol[8]  = gdImageColorAllocate(im,   0,204,204); /* cyan */
1187 	iDartCol[9]  = gdImageColorAllocate(im, 153,153,  0); /* brown */
1188 	iDartCol[10] = gdImageColorAllocate(im, 153, 51,255); /* violet */
1189 	iDartCol[11] = gdImageColorAllocate(im,   0,153,153); /* blue-green */
1190 	iDartCol[12] = gdImageColorAllocate(im,   0,204,102); /* teal */
1191 
1192 	StartLoc = ImageSize - numhitsdisplayed*30;
1193 	ImgMapOrDraw(FALSE, Fsid, vpp, numhitsdisplayed, iKept, selnbrstring,
1194 		selsdidstring, sortby, subsetnum, pagenum, StartLoc, JobID,
1195 		pcPass, NULL);
1196 
1197 	gdImageGif(im, stdout);
1198         gdImageDestroy(im);
1199 
1200 } /* DrawStrucNeig */
1201 
1202