1 /*
2 * $Id: mmdbuti.cpp,v 1.1 2005/07/26 17:11:46 chenj Exp $
3 *
4 *
5 * ===========================================================================
6 *
7 *                            PUBLIC DOMAIN NOTICE
8 *               National Center for Biotechnology Information
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 have not placed any restriction on its use or reproduction.
16 *
17 *  Although all reasonable efforts have been taken to ensure the accuracy
18 *  and reliability of the software and data, the NLM and the U.S.
19 *  Government do not and cannot warrant the performance or results that
20 *  may be obtained by using this software or data. The NLM and the U.S.
21 *  Government disclaim all warranties, express or implied, including
22 *  warranties of performance, merchantability or fitness for any particular
23 *  purpose.
24 *
25 *  Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 *
30 * Author:  Jie Chen
31 * Source file for VSMmdb.cgi
32 *
33 *
34 * $Log: mmdbuti.cpp,v $
35 * Revision 1.1  2005/07/26 17:11:46  chenj
36 * Making linux VSMmdb.cgi
37 *
38 * Revision 1.3  2003/01/15 16:13:42  chenj
39 * add uid as an argument to ChainScaleMapOrImg()
40 *
41 * Revision 1.2  2002/12/26 21:21:20  chenj
42 * use Dart_CdNum() to get all Cds in database
43 *
44 * Revision 1.1.1.1  2002/12/04 21:12:08  chenj
45 * Imported sources
46 *
47 *
48 *
49 *=============================================================================
50 */
51 
52 
53 
54 #include <corelib/ncbiexec.hpp>
55 #include <corelib/ncbifile.hpp>
56 #include "VastSrchUti.hpp"
57 #include "SHGlobal.hpp"
58 #include "mmdbuti.hpp"
59 #include "qman.hpp"
60 #include "dart_external.hpp"
61 
62 #include <cddapi.h>
63 #include "dartutil.h"
64 
65 
66 
67 int	*ColorIdx;
68 
69 static string tmp_dir = "/tmp/";
70 
71 
72 // Initialization
73 unsigned 	ImgInfo :: id = 0;
74 unsigned 	ImgInfo :: chbeg = 0;
75 unsigned 	ImgInfo :: chend = 0;
76 unsigned 	ImgInfo :: imgsize = 0;
77 string 	 	ImgInfo :: subset;
78 bool	 	ImgInfo :: ismap = true;
79 int	 	ImgInfo :: white = 0;
80 int	 	ImgInfo :: black = 0;
81 int	 	ImgInfo :: blue = 0;
82 int	 	ImgInfo :: red = 0;
83 int	 	ImgInfo :: gray = 0;
84 int	 	ImgInfo :: maxseqlen = 0;
85 double	 	ImgInfo :: pix_per_res = 0;
86 vector<int>	ImgInfo :: DartColr;
87 vector<int>	ImgInfo :: Cn3DColr;
88 unsigned	ImgInfo :: prot_ch_cnt = 0;
89 unsigned	ImgInfo :: nucl_ch_cnt = 0;
90 
91 
92 
93 string ImgConf :: VastUrl;
94 string ImgConf :: VastCgi;
95 string ImgConf :: CddUrl;
96 string ImgConf :: CddCgi;
97 string ImgConf :: EntrezUrl;
98 string ImgConf :: EntrezCgi;
99 
100 
101 using namespace SHProjNS;
102 using namespace ncbi;
103 
104 void
ChainScaleMapOrImg(gdImagePtr im,unsigned short x,unsigned short y,PMMD pmmd,unsigned sdid,unsigned color,unsigned labelcol,CCgiContext & ctx,bool VastLink)105 ChainScaleMapOrImg(gdImagePtr im, unsigned short x, unsigned short y,
106 	PMMD pmmd, unsigned sdid, unsigned  color, unsigned labelcol,
107 	CCgiContext& ctx, bool VastLink)
108 {
109     Char    *chain;
110     string  cTmp;
111     unsigned short 	x0, x1, y1, x2, y2, right, seqlen;
112     unsigned    i, len, tick, ntick, dont;
113     static  unsigned   ticksteps[14] ={5, 10, 20, 25, 50, 100, 200, 150, 500,
114 				  1000, 2000, 2500, 5000, 10000};
115     CCgiResponse& resp = ctx.GetResponse();
116     static ImgConf thisConf;
117     static ImgInfo Iinfo;
118 
119     seqlen = pmmd->iResCount;
120     chain = pmmd->pcMolName;
121     right = x2 = (unsigned)(x+ (seqlen-1)*Iinfo.pix_per_res);
122     y2 = y + FontBH + 2;
123 
124     if (Iinfo.ismap)  {
125 
126  	if (!VastLink) cTmp = ToString(seqlen) + " residues.";
127         else
128 	   cTmp = ToString(seqlen) +
129 			" residues, click to see its structure neighbors.";
130 
131         resp.out() << "<area shape=rect coords=" << x
132 		<< "," << y << "," << x2 << "," << y2;
133         if (VastLink) {
134 
135 	    resp.out()<< " href=\"" << thisConf.VastUrl << thisConf.VastCgi
136 	    		<< "?reqid=" << JobId2GrpId(Iinfo.id)
137 			<< "&subsetstr=" << Iinfo.subset.substr(0,3)
138 	    		<< "&sdid=" << sdid << "\"";
139        	}
140         resp.out() << " alt=\"" << cTmp << "\" title=\"" << cTmp << "\">\n";
141 
142     }
143     else {
144         gdImageFilledRectangle(im, x, y, x2, y2, color);
145         cTmp = (string)"Chain " + chain;
146 
147         if ((right - x) >= (int)cTmp.size()*FontBW) {
148 	    x1 = (x + right - cTmp.size()*FontBW)/2;
149 	    gdImageString(im, gdFont7X13b,x1,y+1,(char*)cTmp.c_str(), labelcol);
150         }
151         else if ((right-x) >= (int)cTmp.size()*FontMW) {
152 	    x1 = (x + right - cTmp.size()*FontMW)/2;
153 	    gdImageString(im, gdFont6X12,x1,y+1,(char*)cTmp.c_str(), labelcol);
154         }
155         else if ((right-x) >= (int)strlen(chain)*FontBW) {
156 	    x1 = (x + right - strlen(chain)*FontBW)/2;
157 	    gdImageString(im, gdFont7X13b, x1, y+1, chain, labelcol);
158         }
159         else if ((right-x) >= (int)strlen(chain)*FontMW) {
160 	    x1 = (x + right - strlen(chain)*FontMW)/2;
161 	    gdImageString(im, gdFont6X12, x1, y+1, chain, labelcol);
162         }
163 
164 	/* add ticks */
165        	gdImageLine(im, x, y, x, y-5, Iinfo.red);    /* for "1"  */
166         gdImageLine(im, x2, y, x2, y-5, Iinfo.red);    /* for "len" */
167 
168         y1= y- (5 + FontMH);
169         gdImageString(im, gdFont6X12, x-2, y1, (char *)"1", Iinfo.red);   // "1"
170         x0 = x+FontMW;
171         cTmp[0] = '\0';
172         cTmp = ToString(seqlen);
173         x2 -= (cTmp.size()-1)*FontMW;
174         if (x2 > x)
175            gdImageString(im, gdFont6X12, x2, y1, (char*)cTmp.c_str(),Iinfo.red);
176 								   /* "len" */
177         if ((float)(seqlen-1)/(float)(Iinfo.maxseqlen-1)< 0.05) return;
178 
179         dont = x2 - FontMW;
180 
181         for (i=0; i< 14; i++) {
182 	    ntick = seqlen/ticksteps[i];
183 	    if (ntick < 10)  {
184 		tick = ticksteps[i];
185 		break;
186 	    }
187         }
188 
189         for (i=1; i<= ntick; i++) {
190              x1 = (unsigned)(x + ((float)(i*tick)-1.0)*Iinfo.pix_per_res);
191              if (x1 > right-FontMW)  continue;
192              y1 = y; y2 = y-5;
193              gdImageLine(im, x1, y1, x1, y2, Iinfo.red);
194              cTmp = ToString(i*tick);
195              len = cTmp.size() * FontMW/2;
196              x2  = x1 + len;
197              x1 -= len;
198              y1 -=  (5+ FontMH);
199              if (x2 < dont && ((x2-x0) > (int)len)) {
200                 gdImageString(im, gdFont6X12, x1, y1, (char*)cTmp.c_str(),
201 								Iinfo.red);
202                 x0 = x2+FontMW;
203             }
204         }
205      }
206 
207 } /* end of ChainScaleMapOrImg */
208 
209 
210 
ChainDomMapOrImg(gdImagePtr im,unsigned short x,unsigned short y,PMMD pmmd,unsigned * DomIdx,IntervalHead ** DomHead,CCgiContext & ctx,bool VastLink)211 unsigned short ChainDomMapOrImg(gdImagePtr im, unsigned short x,
212 		unsigned short y, PMMD pmmd, unsigned * DomIdx,
213 		IntervalHead **DomHead, CCgiContext& ctx, bool VastLink)
214 {
215     string                  cTom;
216     unsigned                    x1, x2, y1, y2, ytmp = 0, idx, chnNo;
217     unsigned                    colidx, from, to, seqlen, color=0;
218     unsigned		    right, labelcol=0;
219     ResidueIntervalPntrPtr  ripp;
220     IntervalHead	    *tmp_head;
221     static ImgInfo Iinfo;
222     static ImgConf thisConf;
223     CCgiResponse& resp = ctx.GetResponse();
224 
225     chnNo = (unsigned)pmmd->iChainId;
226     idx = DomIdx[chnNo];
227     seqlen = (unsigned)pmmd->iResCount;
228     right = (unsigned)(x + (float)(seqlen-1)*Iinfo.pix_per_res);
229 
230     if (DomHead[idx] == NULL) { 	/* no 3d domain */
231 	if (!Iinfo.ismap) {
232 	    colidx = ColorIdx[idx];
233 	    color = Iinfo.Cn3DColr[colidx];
234 
235 	    labelcol = Iinfo.white;
236 	    if (colidx==3 || colidx==4 || colidx==5 || colidx==7
237 		|| colidx==8 || colidx==9)
238 		labelcol = Iinfo.black;
239 	}
240 
241 	ChainScaleMapOrImg(im, x, y, pmmd, Dom2Sdi(Iinfo.id, chnNo, 0),
242 					color, labelcol, ctx, VastLink);
243 
244 	ytmp = y+FontBH+4;
245     }
246     else {		/* having 3d domain */
247 	unsigned	i;
248 
249 	x1 = 10;
250 	x2 = x1 + strlen("3d Domains")*FontBW;
251 	y1 = y + FontBH + 6;
252 	y2 = y1+ FontBH;
253 	if (!Iinfo.ismap) {
254 	    gdImageLine(im, x1, y2, x2, y2, Iinfo.blue);
255 	    gdImageString(im,gdFont7X13b, x1, y1, (char *)"3d Domains",
256 								Iinfo.blue);
257 	}
258 
259 	for (tmp_head = DomHead[idx], i=1; tmp_head != NULL;
260 	     tmp_head = tmp_head->next, i++) {
261                 colidx = tmp_head->colidx;
262                 ripp = tmp_head->ripp;
263 
264                 if (i == 1) {
265 		    unsigned   lablecol;
266 
267 		    if (Iinfo.ismap) color = lablecol = 0;
268 		    else {
269 			color = Iinfo.gray;
270 			lablecol = Iinfo.white;
271 		    }
272 		    ChainScaleMapOrImg(im, x, y, pmmd,
273 			Dom2Sdi(Iinfo.id, chnNo, 0), color, lablecol,
274 			ctx, VastLink);
275                 }
276 
277                 y1 = y + FontBH + 6;
278                 y2 = y1 + FontBH + 2;
279                 ytmp = y2;
280 
281                 for (; ripp != NULL; ripp = ripp->next) {
282 		    from = ripp->from;   /* domain range */
283 		    to = ripp->to;
284 		    CalCoor(&x1, &x2,x,from,to,Iinfo.pix_per_res,MaxSeqImgSize);
285 		    x1 = MAX(x1, x);
286 		    x2 = MIN(x2, right);
287 		    if (Iinfo.ismap) {
288 
289 			cTom="Residues " + ToString(from) +" to " +ToString(to);
290   			if (VastLink)
291 				cTom += ", click for structure neighbors";
292 
293                         resp.out()<<"<area shape=rect coords="
294 				      <<x1 <<"," <<y1 <<"," <<x2 <<"," <<y2;
295 			if (VastLink) {
296                             resp.out() <<" href=\"" << thisConf.VastUrl
297 				<< thisConf.VastCgi
298 				<< "?reqid=" << JobId2GrpId(Iinfo.id)
299 				<< "&subsetstr="
300 				<< Iinfo.subset.substr(0, 3)
301 			        << "&sdid="
302 			        <<Dom2Sdi(Iinfo.id, chnNo, tmp_head->domCumid);
303 			};
304 			resp.out() <<"\" alt=\"" << cTom <<"\" title=\""
305 			              <<cTom <<"\">\n";
306 		    }
307 		    else {
308                         gdImageFilledRectangle(im, x1, y1, x2, y2,
309 				Iinfo.Cn3DColr[colidx]);
310 
311                         cTom = ToString(tmp_head->thisdomain);
312 
313                         if ((x2 - x1 - 4) > cTom.size()*FontBW) {
314 			    int  x3;
315 
316 			    x3=(x1+x2 - cTom.size()*FontBW)/2;
317 			    if (colidx==3 || colidx==4 || colidx==5
318 				|| colidx==7 || colidx==8 || colidx==9)
319 				color = Iinfo.black;
320 			    else color = Iinfo.white;
321 			    gdImageString(im, gdFont7X13b, x3, y1+1,
322 				(char*)cTom.c_str(), color);
323                         }
324 		    }
325                 }  /* ; ripp != NULL */
326 
327            }    /* tmp_head */
328     }
329 
330     return(ytmp);
331 }
332 
333 
MaxSeqLenProOrDRna(PMSD pmsd,unsigned short protein)334 short MaxSeqLenProOrDRna(PMSD pmsd, unsigned short protein)
335 {
336         unsigned short    tmp_maxseqlen = 0;
337         PMMD    pmmd;
338         PDNMM   pdnmm;
339 
340         tmp_maxseqlen = 0;
341         for (pdnmm = pmsd->pdnmmHead; pdnmm != NULL; pdnmm = pdnmm->next)
342         {
343                 pmmd = (PMMD) pdnmm->data.ptrvalue;
344                 if ((protein && (pmmd->bWhat & AM_PROT))
345 			|| (!protein && (pmmd->bWhat & (AM_DNA | AM_RNA)))) {
346                         if (tmp_maxseqlen < pmmd->iResCount)
347                                 tmp_maxseqlen = pmmd->iResCount;
348                 }
349         }
350 
351         return(tmp_maxseqlen);
352 
353 }       /* end MaxSeqLen */
354 
355 
356 
357 
PdnmmforChainX(PDNMM pdnmm,unsigned short chainx)358 PDNMM PdnmmforChainX(PDNMM pdnmm, unsigned short chainx)
359 {
360         unsigned short    i = 1;
361         PDNMM   pdnmmtmp;
362         PMMD    pmmd;
363 
364         pdnmmtmp = pdnmm;
365 
366         while (i <= chainx)
367         {
368                 pmmd = (PMMD)(pdnmmtmp->data.ptrvalue);
369                 if ((pmmd->bWhat & (AM_PROT |AM_DNA | AM_RNA)) && pdnmm)
370                         i++;
371                 if (i <= chainx) pdnmmtmp = pdnmmtmp->next;
372         }
373 
374         return(pdnmmtmp);
375 
376 }       /* end PdnmmforChainX */
377 
378 
379 
380 
381 void
GetDomFeaPtr(BiostrucPtr bsp,bool * hasDomain,BiostrucFeaturePtr * domain_bfp)382 GetDomFeaPtr(BiostrucPtr bsp, bool *hasDomain, BiostrucFeaturePtr *domain_bfp)
383 {
384         BiostrucFeatureSetPtr bfsp = NULL;
385         ValNodePtr      vnp = NULL;
386 
387         *domain_bfp = NULL;
388         *hasDomain = FALSE;
389 
390         for (bfsp = bsp->features; bfsp != NULL; bfsp = bfsp->next)
391         {
392              for (vnp = bfsp->descr; vnp != NULL; vnp = vnp->next)
393                   if (vnp->choice == BiostrucFeatureSetDescr_name &&
394                         !StringCmp((char *)vnp->data.ptrvalue, (char *)"NCBI Domains"))
395                   {
396                         *hasDomain = TRUE;
397                         *domain_bfp = bfsp->features;
398                         break;
399                   }
400         }
401 
402 
403 }	/* end of GetDomFeaPtr */
404 
405 
406 
407 
ChainCount(PMSD pmsd)408 unsigned short ChainCount(PMSD pmsd)
409 {
410         unsigned short            cnt;
411         PMMD            pmmd;
412         PDNMM           pdnmm;
413 
414         for (pdnmm = pmsd->pdnmmHead, cnt=0; pdnmm != NULL; pdnmm =pdnmm->next)        {
415                 pmmd = (PMMD) pdnmm->data.ptrvalue;
416                 if ((pmmd->bWhat) & (AM_PROT |AM_DNA | AM_RNA))
417                         cnt++;
418         }
419 
420         return(cnt);
421 
422 }       /* end ChainCount */
423 
424 
425 
GroupingChains(PMSD pmsd)426 void GroupingChains(PMSD pmsd)
427 {
428 
429         unsigned short    i, cnt;
430         PDNMM   prohead, proend, nuhead, nuend, pdnmm, pdnmmnext;
431         PDNMM   elsehead, elseend;
432         PMMD    pmmd;
433 
434 
435         prohead = proend = nuhead = nuend = elsehead = elseend = NULL;
436         pdnmm = pmsd->pdnmmHead;
437 
438         cnt = ChainCount(pmsd);
439 
440         for (i=0, pdnmm = pmsd->pdnmmHead; i< cnt; i++)
441         {
442                 pmmd = (PMMD) pdnmm->data.ptrvalue;
443                 pdnmmnext = pdnmm->next;
444 
445                 if (pmmd->bWhat & AM_PROT)
446                 {
447                     if (!prohead) prohead = proend = pdnmm;
448 		    else {
449                         proend->next = pdnmm;
450                         proend = pdnmm;
451                     }
452                 }
453                 else if (pmmd->bWhat & (AM_DNA | AM_RNA)) {
454                         if (!nuhead) nuhead = nuend = pdnmm;
455                         else {
456                                 nuend->next = pdnmm;
457                                 nuend = pdnmm;
458                         }
459                 }
460                 else i--;
461 
462                 pdnmm->next = NULL;
463                 pdnmm = pdnmmnext;
464         }
465 
466 
467         if (!pdnmm)
468                 if (!elsehead) elsehead = pdnmm;
469                 else elseend->next = pdnmm;
470         elsehead = elseend = NULL;  /* remove non_PROT,non_DNA and non_RNA */
471 	/* ??? */
472 
473         if (!prohead) {
474                 if (!nuhead) pmsd->pdnmmHead = elsehead;
475                 else {
476                         pmsd->pdnmmHead = nuhead;
477                         nuend->next = elsehead;
478                 }
479         }
480         else {
481                 pmsd->pdnmmHead = prohead;
482                 if (!nuhead) proend->next = elsehead;
483                 else {
484                         proend->next = nuhead;
485                         nuend->next = elsehead;
486                 }
487         }
488 
489         ((PDNMM)pmsd->pdnmmHead)->last = NULL;
490 
491 }       /* end GroupingChains */
492 
493 
494 
CalDomIdx(PDNMM pdnmm,unsigned ** DomIdx)495 void CalDomIdx(PDNMM pdnmm, unsigned **DomIdx)
496 {
497 	unsigned	cnt, chnNo, maxchnNo=0;
498 	PMMD	pmmd;
499 	PDNMM	tmp_pdnmm;
500 
501         for (tmp_pdnmm = pdnmm; tmp_pdnmm != NULL; tmp_pdnmm = tmp_pdnmm->next)
502         {
503               pmmd = (PMMD) tmp_pdnmm->data.ptrvalue;
504               if (pmmd->bWhat & (AM_PROT | AM_DNA |AM_RNA)) {
505                     chnNo = pmmd->iChainId;
506                     if (maxchnNo < chnNo) maxchnNo = chnNo;
507               }
508         }
509 
510         maxchnNo ++;
511         *DomIdx = NewDataType <unsigned>(maxchnNo);
512 
513         for (tmp_pdnmm = pdnmm, cnt=0; tmp_pdnmm != NULL;
514                                         tmp_pdnmm = tmp_pdnmm->next, cnt++)
515         {
516              pmmd = (PMMD) tmp_pdnmm->data.ptrvalue;
517              if (pmmd->bWhat & (AM_PROT | AM_DNA |AM_RNA))
518                  (*DomIdx)[pmmd->iChainId] = cnt;
519         }
520 
521 }	/* CalDomIdx */
522 
523 
524 
525 void
CheckDomColIdx(BiostrucFeaturePtr bfp,PDNMM pdnmm,IntervalHead ** DomHead,unsigned * DomIdx,bool hasDomain,bool forImg)526 CheckDomColIdx(BiostrucFeaturePtr bfp, PDNMM pdnmm, IntervalHead **DomHead,
527 unsigned *DomIdx, bool hasDomain, bool forImg)
528 {
529 	BiostrucFeaturePtr	tmp_bfp;
530 	unsigned short			colidx = 0, thisdomain;
531 	unsigned 			chnNo;
532 	IntervalHead		*tmp_head;
533 	PDNMM			tmp_pdnmm;
534 	PMMD			pmmd;
535 	ResidueIntervalPntrPtr	ripp;
536 	ValNodePtr		vnp, vnp1, vnp2;
537 
538 	if (hasDomain) {
539 	   for (tmp_bfp = bfp; tmp_bfp != NULL; tmp_bfp = tmp_bfp->next)
540 	   {
541 		unsigned  idx;
542 
543                 vnp = tmp_bfp->Location_location;
544                 vnp1 = (ValNodePtr) vnp->data.ptrvalue;
545                 vnp2 = (ValNodePtr) vnp1->data.ptrvalue;
546 
547                 ripp = (ResidueIntervalPntrPtr) vnp2->data.ptrvalue;
548 		chnNo = ripp->molecule_id;
549 
550 		colidx %= ncycle;
551 		idx = DomIdx[chnNo];
552 		 if (DomHead[idx] == NULL)  {
553 		     thisdomain = 1;
554 		     if (forImg == TRUE) ColorIdx[idx] = -11; /*just a label */
555 		}
556 		else thisdomain++;
557 
558 		tmp_head = NewDataType <IntervalHead> (1);
559 		tmp_head->colidx = colidx;
560 		tmp_head->ripp = ripp;
561 		tmp_head->next = DomHead[idx];
562 		tmp_head->thisdomain = thisdomain;
563 		tmp_head->domCumid = tmp_bfp->id;
564 		DomHead[idx] = tmp_head;
565 
566 		colidx++;
567 	   }	/* tmp_bfp */
568 	}	/* if (hasDomain) */
569 
570 	for (tmp_pdnmm = pdnmm; tmp_pdnmm != NULL; tmp_pdnmm = tmp_pdnmm->next)
571 	{
572 	     unsigned  idx;
573 
574 	     pmmd = (PMMD) tmp_pdnmm->data.ptrvalue;
575 	     if (pmmd->bWhat & (AM_PROT | AM_DNA |AM_RNA)) {
576 
577 		chnNo = pmmd->iChainId;
578 		idx = DomIdx[chnNo];
579 		if (DomHead[idx] == NULL) {
580 			colidx %= ncycle;
581 			if (forImg==TRUE) ColorIdx[idx] = colidx;
582 			colidx++;
583 		}
584 	     }
585 
586 	}	/* for (tmp_pdnmm) */
587 
588 
589 }	/* CheckDomColIdx */
590 
591 
592 
ChainNameMapOrImg(gdImagePtr im,unsigned short x,unsigned short y,unsigned short protein)593 unsigned short ChainNameMapOrImg(gdImagePtr im, unsigned short x,
594 				unsigned short y, unsigned short protein)
595 {
596     unsigned short        x1, x2, y2;
597     string	tmpstr;
598     static 	ImgInfo Iinfo;
599 
600     if (protein) tmpstr = "Protein";
601     else tmpstr = "Nucleotide";
602 
603     x1 = x+10;
604     x2 = x1 + tmpstr.size()*FontBW;
605     y2 = y+FontBH;
606 
607     if (!Iinfo.ismap) {
608         gdImageString(im,gdFont7X13b, x1, y, (char*)tmpstr.c_str(),Iinfo.blue);
609 //        gdImageLine(im, x1, y2, x2, y2, Iinfo.blue);
610     }
611 
612     return(x2);
613 }
614 
615 
616 
CDDMapOrImg(gdImagePtr im,unsigned short x,unsigned short y,PMSD pmsd,PMMD pmmd,CCgiContext & ctx)617 static unsigned short CDDMapOrImg(gdImagePtr im, unsigned short x,
618 		unsigned short y, PMSD pmsd, PMMD pmmd, CCgiContext& ctx)
619 {
620     char                **CddName;
621     string 		cTmp, str;
622     OverLoc             *end, *head;
623     unsigned            right, i, j, dy=0, y0, x1, x2, y1, y2, gi, seqlen;
624     unsigned            numseg, from, to, len1, len2, alinumseg, index;
625     int           	*starts, *lens;
626     SeqAnnotPtr         sap = NULL;
627     SeqAlignPtr         salp = NULL;
628     DenseSegPtr         *dsp;
629     SeqEntryPtr         sep=NULL;
630     BioseqPtr           bseqp=NULL;
631     static ImgInfo	Iinfo;
632     CCgiResponse& 	resp = ctx.GetResponse();
633     static ImgConf	thisConf;
634 
635 //    unsigned chnNo = pmmd->iChainId;
636     gi = GetVSGi(Iinfo.id, pmmd->iChainId);
637 
638     if (!gi) return (y);
639 
640     seqlen = pmmd->iResCount;
641     right = (unsigned)(x + (float)(seqlen-1)*Iinfo.pix_per_res);
642 
643     sep = (SeqEntryPtr) GetVSSeqEntryForGi(gi, false, NULL);
644 
645     if (!sep) return (y);
646     bseqp = (BioseqPtr)sep->data.ptrvalue;
647 
648     if (!bseqp) {
649 
650 	str = "<h3>SeqEntryPtr not NULL, but BioseqPtr is NULL and gi="
651 		+ ToString(gi) + ".</h3>\n";
652 	PrtMes::PrintErrorHeader(&resp, "VastSrch", 1);
653       	PrtMes::PrintMsgWithTail(&resp, str);
654 
655       	ERR_POST("bseqp = NULL");
656       	throw exception();
657     }
658 
659 //curtime = CTime(CTime::eCurrent).AsString();
660 //cerr << "before CddSynchronousQuery " << curtime << endl;
661 //    sap = CddSynchronousQuery(bseqp, 0.01, true, true, false, "", false);
662 
663 sap = NULL;
664 /*
665     if (sap) {
666 
667         unsigned        *PssmId;
668         unsigned short  *iColor, CdNum, thisColor=0;
669 	short		*iClus;
670         string          querynm, shortname, defline, definition;
671         string          def2, cdalign;
672 
673         end = head = NewOverLoc(seqlen);
674         head->y = y0 = y+5;
675 
676         for (salp = (SeqAlignPtr)sap->data, CdNum=0; salp!=NULL;
677              salp=salp->next, CdNum++);
678 
679         iColor = NewDataType <unsigned short> (CdNum);
680         PssmId = NewDataType <unsigned> (CdNum);
681 	dsp = NewDataType <DenseSegPtr> (CdNum);
682         CddName = NewDataType <CharPtr> (CdNum);
683         for (j=0; j< CdNum; j++) {
684                 CddName[j] = NewDataType <char>(30);
685                 CddName[j][0] = '\0';
686         }
687         iClus = NewDataType <short> (CdNum);
688 
689 	string strtmp;
690         for (salp = (SeqAlignPtr)sap->data, i=0; salp!=NULL;
691                                                 salp=salp->next, i++) {
692             dsp[i] = (DenseSegPtr)salp->segs;
693             PssmId[i] = GetPSSMID(dsp[i]);
694             iClus[i] = -1;
695 
696             if (PssmId[i]) {
697                 Dart_CDGi2Acc_external(PssmId[i], strtmp);
698 		sprintf(CddName[i], strtmp.c_str());
699 	    }
700             else {
701 		THROWS("PssmId = 0");
702 	    }
703         }
704 
705         for (i=0; i< CdNum; i++) {
706              if (iClus[i] >= 0) continue;
707 
708              iClus[i] = i;
709              if (!Iinfo.ismap)
710 			iColor[i] = (thisColor++) % Iinfo.DartColr.size();
711              for (j = i+1; j< CdNum; j++) {
712                   if (PssmId[i] == PssmId[j]) {
713                       if (!Iinfo.ismap) iColor[j] = iColor[i];
714                       iClus[j] = i;
715                   }
716              }
717         }
718 
719 	strtmp = pmmd->pcMolName;
720 	querynm = "query";
721  	if (strtmp != "") querynm += "_" + strtmp;
722 
723         for (i=0; i< CdNum; i++) {
724 
725             numseg = (dsp[i])->numseg;
726             starts = (dsp[i])->starts;
727             lens = (dsp[i])->lens;
728             from  = starts[0] + 1;
729             to = starts[(numseg-1)*2] + lens[numseg-1];
730 
731             CalCoor(&x1, &x2, x, from, to, Iinfo.pix_per_res, MaxSeqImgSize);
732             x1 = MAX(x, x1);
733             x2 = MIN(x2, right);
734 
735             y1= GetY_nr_cddsrv(head, &end, from, to, seqlen, 7);
736             y2 = y1+FontBH+4;
737 
738             Dart_Acc2Info_external(CddName[i], shortname, defline, definition);
739 
740             if (Iinfo.ismap) {
741 
742                 if (defline.size() == 254)
743 			defline.replace(defline.size()-4, 3, "...");
744 		if (defline[defline.size()-1] != '.') defline += ".";
745 
746         	unsigned pos = defline.find(';');
747         	if (pos != string::npos) def2 = defline.substr(0, pos-1);
748         	else {
749 
750              		pos = defline.find('.');
751              		if (pos != string::npos) def2 = defline.substr(0, pos);
752              		else def2 = defline + ".";
753         	}
754         	def2 = (string)CddName[i] + ":" + def2
755 						+ "Click for the CD alignment.";
756 
757                 alinumseg = 0;
758                 cdalign = "";
759                 for (j=0; j< numseg; j++) {
760                     index = 2*j;
761                     if (starts[index]!= -1 && starts[index+1] != -1) {
762 
763 			cdalign += "," + ToString(starts[index+1]) + ","
764                                 + ToString(starts[index]) + ","
765                                 + ToString(lens[j]);
766                         alinumseg++;
767                     }
768                 }
769 		strtmp = ToString(alinumseg) + cdalign;
770 
771 //
772                 resp.out() << "<area shape=rect coords="
773 			<< x1 << ","
774 			<< y1 << ","
775 			<< x2 << ","
776 			<< y2 << " "
777 			<< "href=\"" << thisConf.CddUrl << thisConf.CddCgi
778 			<< "?ascbin=2&maxaln=10&seltype=3&uid=" << PssmId[i]
779 			<< "&aln=" << strtmp
780 			<< "&querygi="
781 			<< "&querynm=" << querynm << "\" "
782 			<< "alt=\"" << CddName[i] << ": " << defline
783 			<< " Click to see CD alignment.\" title=\""
784 			<< CddName[i] << ": " << defline
785 			<< " Click to see CD alignment.\">\n";
786 //
787 
788 
789 		cTmp += ("+OR+" + ToString(PssmId[i]) + "[uid]");
790 
791             }
792             else {    // ismap == FALSE
793 
794                 gdImageRoundRectangle(im, x1, y1, x2, y2, 8, 5,
795 						Iinfo.DartColr[iColor[i]], 1);
796 
797                 len1 = shortname.size()*FontBW;
798                 len2 = shortname.size()*FontMW;
799 
800                 int color = Iinfo.white;
801                 if (iColor[i] ==2 || iColor[i] ==4 || iColor[i]==0)
802 							color=Iinfo.black;
803                 if ((x2-x1-4)> len1)
804                     gdImageString(im, gdFont7X13b, (x1+x2-len1)/2, y1+2,
805                                   (char *)shortname.c_str(), color);
806                 else if ((x2-x1-4) > len2)
807                     gdImageString(im, gdFont6X12, (x1+x2-len2)/2, y1+2,
808                                   (char *)shortname.c_str(), color);
809                 else {
810                     Int4  char_num;
811 
812                     char_num = (x2-x1-4)/FontBW;
813                     if (char_num >= 3)
814 			shortname.replace(shortname.size() -3, 3, "...");
815                     else switch (char_num) {
816                         case 1: shortname = "."; break;
817                         case 2: shortname = "..";
818                     }
819                     gdImageString(im,gdFont7X13b,x1+4, y1+2,
820 					(char*)shortname.c_str(), color);
821                 }
822             }
823 
824             if (!dy) {
825                 dy = y0-y1;
826                 y0 = y1;
827             }
828         }       // for
829 
830         y0 = y2;
831 
832         if (!dy) dy=6;
833         else dy = 15;
834 
835         x1 = 10;
836         x2 = x1+ StrLen("CDs") * FontBW;
837         y1 = y+dy;
838         y2 = y1+FontBH;
839         if (!Iinfo.ismap) {
840             gdImageLine(im, x1, y2, x2, y2, Iinfo.blue);
841             gdImageString(im, gdFont7X13b, x1, y1, (char *)"CDs", Iinfo.blue);
842         }
843         else {
844             strtmp = "Click to see Entrez Conserved Domains.";
845 	    resp.out() << "<area shape=rect coords=" << ToString(x1) << ","
846 			<< ToString(y1) << "," << ToString(x2) << ","
847 			<< ToString(y2) << " href=\""
848 			<< thisConf.EntrezUrl << thisConf.EntrezCgi
849 			<< "?db=cdd&term=" << cTmp.substr(3)
850 			<< "\" alt=\"" << strtmp
851 			<< "\" title=\"" << strtmp << "\">\n";
852         }
853         y2 = y0;
854 
855         for (end = head; end != NULL; end = end->next) delete end;
856         delete [] iColor;
857         delete [] PssmId;
858         delete [] dsp;
859         for (i=0; i< CdNum; i++) delete [] CddName[i];
860         delete [] CddName;
861         delete [] iClus;
862     }
863     else y2 = y;
864 */
865 	y2=y;  // because the above block.
866 
867     return(y2);
868 
869 }  // end of CDDMapOrImg
870 
871 
872 
873 
ModelMapOrImg(gdImagePtr im,PMSD pmsd,IntervalHead ** DomHead,unsigned * DomIdx,CCgiContext & ctx,bool VastLink)874 unsigned short ModelMapOrImg(gdImagePtr im, PMSD pmsd, IntervalHead **DomHead,
875 		unsigned * DomIdx, CCgiContext& ctx, bool VastLink)
876 {
877     PDNMM		pdnmm, pdnmm1;
878     PMMD 		pmmd;
879     unsigned 		i,colidx;
880     unsigned short 	x, y;
881     static ImgInfo 	Iinfo;
882 
883     pdnmm = (PDNMM)pmsd->pdnmmHead;
884     pdnmm1 = PdnmmforChainX(pdnmm, Iinfo.chbeg);
885     pdnmm = pdnmm1;
886 
887 // Protein Chains
888 
889     Iinfo.maxseqlen = MaxSeqLenProOrDRna(pmsd, 1);
890     Iinfo.pix_per_res = (float)MaxSeqImgSize/(float)(Iinfo.maxseqlen-1);
891 /*
892 
893     if (!Dart_InitReal()) {
894 
895         PrtMes::PrintErrorHeader(&(ctx.GetResponse()), "VastSrch", 1);
896         PrtMes::PrintMsgWithTail(&(ctx.GetResponse()),"Dart_InitReal() failed");
897 
898         ERR_POST("Dart_InitReal() failed.");
899         throw exception();
900     }
901 */
902 
903     if (Iinfo.maxseqlen) {
904 	for (i = Iinfo.chbeg; i <= Iinfo.chend; i++, pdnmm = pdnmm->next) {
905 
906 	    pmmd = (PMMD)pdnmm->data.ptrvalue;
907 
908 	    if ((pmmd->bWhat) & (AM_DNA || AM_RNA)) break;
909 	    if ((pmmd->bWhat) & AM_PROT) {
910 
911 		Iinfo.prot_ch_cnt++;
912 
913         // Name
914 		if (i == 1 || i == Iinfo.chbeg) y = 50;
915 		else y += 60;
916 		x = ChainNameMapOrImg(im, 0, y, 1);
917 
918 	// Chain & Domains
919 
920 	       x += 30;
921 	       y=ChainDomMapOrImg(im,x,y, pmmd, DomIdx, DomHead, ctx, VastLink);
922 
923 	// Cdd Image
924 
925 		y = CDDMapOrImg(im, x, y, pmsd, pmmd, ctx);
926 
927 	    }  // AM_PROT
928 
929 	}    // end for (i=chain1
930 
931     }  // end Protein Chains
932 
933 
934 // Nucleotide Chains
935     Iinfo.maxseqlen = MaxSeqLenProOrDRna(pmsd, 0);
936     Iinfo.pix_per_res = (float)MaxSeqImgSize/(float)(Iinfo.maxseqlen-1);
937 
938     if (Iinfo.maxseqlen) {
939         for (i = Iinfo.chbeg, pdnmm = pdnmm1; i <= Iinfo.chend;
940 						i++, pdnmm =pdnmm->next){
941 
942             pmmd = (PMMD)pdnmm->data.ptrvalue;
943 
944             if ((pmmd->bWhat) & (AM_DNA | AM_RNA)) {
945 
946             	unsigned  labelcol;
947 
948 		Iinfo.nucl_ch_cnt++;
949 
950         // Name
951                 if (i==1 || i == Iinfo.chbeg) y = 50;
952                 else y += 80;
953                 x = ChainNameMapOrImg(im, 0, y, 0);
954 
955         // Chain Image
956 
957                 if (!Iinfo.ismap) {
958                     x += 9;
959                     colidx = ColorIdx[DomIdx[pmmd->iChainId]];
960                     labelcol = Iinfo.white;
961                     if (colidx==3 || colidx==4 || colidx==5 || colidx==7
962                         || colidx==8 || colidx==9)
963                         labelcol = Iinfo.black;
964                     ChainScaleMapOrImg(im, x, y, pmmd, 0,
965 				Iinfo.Cn3DColr[colidx], labelcol, ctx, VastLink);
966                 }
967 
968             } 	// AM_DNA | AM_RNA
969 
970         } 	// end nucleotide Chains
971 
972     }  	// end maxseqlen
973 
974 //    Dart_FiniReal();
975 
976     return(y);
977 
978 }	// end of ModelMapOrImg
979 
980 
981 
DrawImg(CCgiContext & ctx)982 void DrawImg(CCgiContext& ctx)
983 {
984 	bool		hasDomain = FALSE;
985 	BiostrucFeaturePtr	domain_bfp;
986 	BiostrucPtr	bsp=NULL;
987 	gdImagePtr      im;
988 	unsigned		i, cnt, *DomIdx;
989 	IntervalHead	*tmp_head;
990 	PDNMS		ModelStruc=NULL;
991 	PDNMM		pdnmm;
992 	PMSD		pmsd;
993 	IntervalHead	**DomHead;
994 	static 		ImgInfo Iinfo;
995 
996 
997        /*
998 	string dir = tmp_dir + "VS" + ToString(Iinfo.id) + "/";
999 	string bFile = dir + "biostr.txt";
1000 
1001         if (!CDir(dir).Exists()) {
1002             CExec::System((string("mkdir ") + dir).c_str());
1003             CExec::System((string("chmod 777 ") + dir).c_str());  // temp.!!!!
1004             string strtmp = "VS" + ToString(Iinfo.id);
1005 	    DownloadBiostrFromDB(strtmp, bFile);
1006         }
1007 
1008 	bsp = FetchBS((char*)bFile.c_str(), 1, 2, 1000, POWER_VIEW);
1009 */
1010 
1011 	bsp = VSOpenBSP(Iinfo.id, 2, 10000);
1012  	if (!bsp) return;
1013 
1014 	ModelStruc = MakeAModelstruc(bsp);
1015 	pmsd = (PMSD) ModelStruc->data.ptrvalue;
1016         pdnmm = pmsd->pdnmmHead;
1017 	cnt = ChainCount(pmsd);
1018 	if (!cnt) return;
1019 
1020 	ColorIdx = NewDataType<int>(cnt);
1021 	DomHead = NewDataType <IntervalHead *> (cnt+1);
1022 	for (i=0; i< cnt; i++) {
1023 		ColorIdx[i] = -1;
1024 		DomHead[i] = NULL;
1025 	}
1026 	CalDomIdx(pdnmm, &DomIdx);
1027 
1028 	GetDomFeaPtr(bsp, &hasDomain, &domain_bfp);
1029 	CheckDomColIdx(domain_bfp, pdnmm, DomHead, DomIdx, hasDomain, TRUE);
1030 
1031         GroupingChains(pmsd);
1032 
1033         im = gdImageCreate(GraphWidth, Iinfo.imgsize);
1034 
1035  	Iinfo.white = gdImageColorAllocate(im, 255, 255, 255);
1036         Iinfo.black = gdImageColorAllocate(im,   0,   0,   0);
1037 	Iinfo.blue =  gdImageColorAllocate(im,   0,   0, 225);
1038 	Iinfo.red  =  gdImageColorAllocate(im, 255,   0,   0);
1039 	Iinfo.gray = gdImageColorAllocate(im, 102, 102, 102);
1040 
1041 
1042 	// Dart Color scheme
1043 	Iinfo.DartColr.reserve( 13 );
1044 	Iinfo.DartColr.push_back(gdImageColorAllocate(im,153,204,255)); // sky b
1045         Iinfo.DartColr.push_back(Iinfo.blue);
1046 	Iinfo.DartColr.push_back(gdImageColorAllocate(im,  0,255,0));  // green
1047         Iinfo.DartColr.push_back(gdImageColorAllocate(im,204,102,0));  // orange
1048         Iinfo.DartColr.push_back(gdImageColorAllocate(im,204,204,0));  // yellow
1049 	Iinfo.DartColr.push_back(Iinfo.red);
1050         Iinfo.DartColr.push_back(gdImageColorAllocate(im,102,153,  0)); //spring
1051         Iinfo.DartColr.push_back(gdImageColorAllocate(im,204,102,153)); // lavender
1052         Iinfo.DartColr.push_back(gdImageColorAllocate(im,  0,204,204)); // cyan
1053         Iinfo.DartColr.push_back(gdImageColorAllocate(im,153,153,  0)); // brown
1054         Iinfo.DartColr.push_back(gdImageColorAllocate(im,153, 51,255));// violet
1055         Iinfo.DartColr.push_back(gdImageColorAllocate(im,  0,153,153)); // blue-green
1056         Iinfo.DartColr.push_back(gdImageColorAllocate(im,  0,204,102)); // teal
1057 
1058 
1059 	// Cn3D Color scheme
1060 	Iinfo.Cn3DColr.reserve( 10 );
1061 	Iinfo.Cn3DColr.push_back(gdImageColorAllocate(im,255, 0, 255));//magenta
1062 	Iinfo.Cn3DColr.push_back(gdImageColorAllocate(im,  0, 0, 255)); // blue
1063 	Iinfo.Cn3DColr.push_back(gdImageColorAllocate(im,139, 87, 66)); // brown
1064 	Iinfo.Cn3DColr.push_back(gdImageColorAllocate(im,0,255,127)); //l. green
1065 	Iinfo.Cn3DColr.push_back(gdImageColorAllocate(im,179,179,179));//l. gray
1066 	Iinfo.Cn3DColr.push_back(gdImageColorAllocate(im,255,165,  0)); // gold
1067 	Iinfo.Cn3DColr.push_back(gdImageColorAllocate(im,255,114, 86)); // pink
1068 	Iinfo.Cn3DColr.push_back(gdImageColorAllocate(im,  0,255,  0)); // green
1069 	Iinfo.Cn3DColr.push_back(gdImageColorAllocate(im,  0,255,255)); // cyan
1070 	Iinfo.Cn3DColr.push_back(gdImageColorAllocate(im,255,236,139));//yel.tint
1071 
1072 
1073 	printf("Content-type: image/gif\n\n");
1074 	Iinfo.ismap = false;
1075 	ModelMapOrImg(im, pmsd, DomHead, DomIdx, ctx, false);
1076 
1077 //        int fd = ctx.GetResponse().GetOutputFD();
1078 //        gdImageGif(im, fd);
1079 
1080         gdImageGif(im, stdout);
1081         gdImageDestroy(im);
1082 
1083 	delete [] ColorIdx;
1084 	for (i = 0; i< cnt; i++)
1085 	  if (DomHead[i] != NULL)  {
1086 		for (tmp_head = DomHead[i]; tmp_head != NULL;
1087 					tmp_head=tmp_head->next)
1088 			delete [] tmp_head;
1089 	  }
1090 	delete [] DomHead;
1091 	delete [] DomIdx;
1092 
1093 //        CExec::System((string("rm -r ") + dir).c_str());
1094 
1095 	return;
1096 
1097 }	/* end DrawImg */
1098