1 /* vast2cn3d.c
2  *
3  * ===========================================================================
4  *
5  *                            PUBLIC DOMAIN NOTICE
6  *            National Center for Biotechnology Information (NCBI)
7  *
8  *  This software/database is a "United States Government Work" under the
9  *  terms of the United States Copyright Act.  It was written as part of
10  *  the author's official duties as a United States Government employee and
11  *  thus cannot be copyrighted.  This software/database is freely available
12  *  to the public for use. The National Library of Medicine and the U.S.
13  *  Government do not place any restriction on its use or reproduction.
14  *  We would, however, appreciate having the NCBI and the author cited in
15  *  any work or product based on this material
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  * ===========================================================================
26  *
27  * File Name: vast2cn3d.c
28  *
29  * Author: Lewis Geer, Chris Hogue
30  *
31  * Version Creation Date: 03/18/98
32  *
33  * $Log: vast2cn3d.c,v $
34  * Revision 6.11  1999/10/13 20:19:35  zimmerma
35  * DZ: Removed use of temporary files - html output redirected to stdout
36  *
37  * Revision 6.10  1998/11/20 20:03:55  addess
38  * related to platform independence of VAST Search
39  *
40  * Revision 6.9  1998/10/14  17:16:35  addess
41  * sending aligned chains to Cn3D
42  *
43  * Revision 6.8  1998/07/17  18:46:30  madej
44  * Various changes, e.g. to support local IDs.
45  *
46  * Revision 6.7  1998/06/17  20:52:06  madej
47  * Fix for See File option in vastsrv.
48  *
49  *
50   */
51 
52 #include <stdio.h>
53 #include <ncbi.h>
54 #include <accentr.h>
55 #include <objalign.h>
56 #include <objseq.h>
57 #include <objmgr.h>
58 #include <lsqfetch.h>
59 #include <netentr.h>
60 #include <www.h>
61 #include <sys/resource.h>
62 #include <mmdbapi.h>
63 #include <mmdbapi1.h>
64 #include "vastlocl.h"
65 #include "mmdblocl.h"
66 #include "mmdbdata.h"
67 #include "vast2mage.h"
68 #include "vastsrv.h"
69 #include "mkbioseq.h"
70 #include <asnmime.h>
71 #include <objmime.h>
72 #include <strimprt.h>
73 
74 
75 
76 static char *BaseURL;
77 static FILE *OutputFile = NULL;
78 static char OutputName[200];
79 #define CPUTIME_MAX 120
80 
81 /* Display a structural alignment in Cn3D. */
82 
VastToCn3D(WWWInfoPtr www_info)83 Boolean LIBCALL VastToCn3D(WWWInfoPtr www_info)
84 {
85 	FILE *pFile = NULL;
86 	FILE *pIn = NULL;
87 	Char pcBuf[100], pcLine[256], giBuf[20], URL[200];
88 	CharPtr pcTest, pcL1 = NULL, Name, www_arg;
89 	Int4 GetGi, Fid, Fsid, iFileExists = 0, indx;
90 	BiostrucAnnotSetPtr pbsa = NULL;
91 	BiostrucAnnotSetPtr pbsaShort = NULL;
92         BiostrucFeatureSetPtr pbsfs = NULL;
93         BiostrucFeaturePtr pbsf = NULL;
94         BiostrucResidueGraphSetPtr stdDictionary;
95         ValNodePtr pvnFids = NULL, pvnFid = NULL;
96         Int2 iTest = 0, iPDB = 0, iColor;
97 	AsnIoPtr aip = NULL;
98 	Byte bRender;
99 	Char *IPAddress = getenv("REMOTE_HOST");
100         Int4 NumLabels, iMMDBId;
101 	ValNode * pbsidThis;
102 	BiostrucPtr pbsMaster, pbsSlave, pbsSlaveHead = NULL, pbsSlaveTail, pbsTemp;
103 	Char szName[5], chain[2];
104 	Char * szTemp;
105   SeqAnnotPtr psaAlignHead = NULL, psaAlignTail;
106   SeqAlignPtr salpHead, salpTail;
107   SeqIdPtr      sip;
108   DenseSegPtr   dsp;
109   BioseqPtr bsp;
110   SeqEntryPtr sep;
111     char  str [52];
112     NcbiMimeAsn1Ptr pvnNcbi;
113     BiostrucAlignPtr pbsaStruct;
114     AsnIoPtr paiFile, aipr;
115     Boolean is_network;
116     Int4 uid, uidmaster = 0;
117  Int2 retcode = 3;
118  CharPtr JobID = NULL, pcPass;
119  Char AsnPath[PATH_MAX];
120  Char AsnName[10];
121  Int2 ret, complexity;
122  Int4 iFidCount = 0;
123  Boolean Chain;
124 
125  /*    SeqAsnLoad();
126 
127 
128     objmmdb1AsnLoad();
129     objmmdb2AsnLoad();
130     objmmdb3AsnLoad();
131     SeqAlignAsnLoad();
132     objmimeAsnLoad();
133     */
134 
135 
136 	if ((indx = WWWFindName(www_info, "uid")) < 0) {
137 		printf("Content-type: text/html\n\n");
138 		printf("<h3>No accession (PDB ID) was input - nothing to report.</h3>\n");
139 		return 0;
140 	}
141 
142 	www_arg =  WWWGetValueByIndex(www_info, indx);
143 
144 	if (isdigit(www_arg[0]))
145 		GetGi = (Int4) atoi(www_arg);
146 	else {
147 		printf("Content-type: text/html\n\n");
148 		printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
149 		printf("<h3>Non-numeric MMDB-id input - no results.</h3>\n");
150 		return 0;
151 	}
152 
153 	/* vsid and pass are to look at alignments from VAST Search */
154 	if ((indx = WWWFindName(www_info, "vsid")) >= 0) {
155 		www_arg = WWWGetValueByIndex(www_info, indx);
156 		JobID = StringSave(www_arg);
157 
158 		if ((indx = WWWFindName(www_info, "pass")) < 0) {
159 			printf("Content-type: text/html\n\n");
160 			printf("<body bgcolor = \"#f0f0f0\">\n");
161 			printf("<h2>VAST SEARCH</h2>\n");
162 			printf("<h3>Password required.</h3>\n");
163 			return 0;
164 		}
165 		else {
166 			www_arg = WWWGetValueByIndex(www_info, indx);
167 			pcPass = StringSave(www_arg);
168 
169 			if ((ret = Check_VastSearch_Password(pcPass, JobID)) != 1) {
170 				if (ret == 2) return 0;
171 				printf("Content-type: text/html\n\n");
172 				printf("<body bgcolor = \"#f0f0f0\">\n");
173 				printf("<h2>VAST SEARCH</h2>\n");
174 				printf("<h3>Incorrect password.</h3>\n");
175 				return 0;
176 			}
177 		}
178 	}
179 
180 	if ((indx = WWWFindName(www_info, "hit")) < 0) {
181 		printf("Content-type: text/html\n\n");
182 		printf("<body bgcolor = \"#f0f0f0\">\n");
183 		printf("<br>\n<h2>No alignment was selected!</h2>\n");
184 		printf("<h3>Please click on up to 5 boxes in the leftmost column of the table.</h3>\n");
185 		return 0;
186 	}
187 
188 	/* loop over all the "hit" values in the list */
189 	NumLabels = WWWGetNumEntries(www_info);
190 
191 	for (indx = 0; indx < NumLabels; indx++) {
192 		Name = WWWGetNameByIndex(www_info, indx);
193 
194 		if (StrICmp(Name, "hit") == 0) {
195 			www_arg = WWWGetValueByIndex(www_info, indx);
196 
197 			if (isdigit(www_arg[0]))
198 				Fid = (Int4) atol(www_arg);
199 			else {
200 				printf("Content-type: text/html\n\n");
201 				printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
202 				printf("<h3>Non-numeric slave alignment code - no results.</h3>\n");
203 				return 0;
204 			}
205 
206 			if (++iFidCount > 5) break;
207 			pvnFid = ValNodeAddInt(&pvnFids, 0, Fid);
208 		}
209  	}
210 
211 	if ((indx = WWWFindName(www_info, "chaindom")) < 0) {
212 		printf("Content-type: text/html\n\n");
213 		printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
214 		printf("<h3>No feature set ID (master alignment code) - nothing to report.</h3>\n");
215 		return 0;
216 	}
217 
218 	www_arg = WWWGetValueByIndex(www_info, indx);
219 
220 	if (isdigit(www_arg[0]))
221 		Fsid = (Int4) atoi(www_arg);
222 	else {
223 		printf("Content-type: text/html\n\n");
224 		printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
225 		printf("<h3>Non-numeric master alignment code - no results.</h3>\n");
226 		return 0;
227 	}
228 
229         if ((indx = WWWFindName(www_info, "chn_complexity")) < 0)
230             Chain = TRUE;
231         else
232         {
233           www_arg = WWWGetValueByIndex(www_info, indx);
234           complexity =(Int2)atoi(www_arg);
235 
236           if (complexity) Chain = TRUE;
237           else Chain = FALSE;
238         }
239 
240 	if ((indx = WWWFindName(www_info, "atm_complexity")) < 0)
241 		/* select alpha Carbons only by default */
242 		complexity = ONECOORDRES;
243 	else {
244 		www_arg = WWWGetValueByIndex(www_info, indx);
245 
246 		if (isdigit(www_arg[0]))
247 			complexity = (Int2) atoi(www_arg);
248 		else
249 			complexity = ONECOORDRES;
250 	}
251 
252 	if ((complexity != ONECOORDRES) && (complexity != ONECOORDATOM))
253 		/* bizarre value, but default to alpha-Carbons only */
254 		complexity = ONECOORDRES;
255 
256 	/* action == 0 indicates MIME; action == 1 is text; action == 2 is save */
257 	if ((indx = WWWFindName(www_info, "action")) < 0)
258 		iPDB = 0;
259 	else {
260 		www_arg = WWWGetValueByIndex(www_info, indx);
261 
262 		if (isdigit(www_arg[0]))
263 			iPDB = (Int4) atoi(www_arg);
264 		else
265 			iPDB = 0;
266 	}
267 
268 	if (VASTInit() != TRUE) {
269 		printf("Content-type: text/html\n\n");
270 		printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
271 		printf("<h3>Can't find VAST data on server.\n");
272 		printf("Contact info@ncbi.nlm.nih.gov</h3>\n");
273 		return 0;
274 	}
275 
276 	OpenMMDBAPI((POWER_VIEW /* ^ FETCH_ENTREZ */), NULL);
277 	pbsa = LocalGetFeatureSet(GetGi, Fsid, JobID);
278 
279         if (pbsa == NULL) {
280 		printf("Content-type: text/html\n\n");
281 		printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
282 		printf("<h3>No master alignment record exists for %ld.</h3>\n", (long) GetGi);
283 		return 0;
284 	}
285 
286 	if (iFidCount == 1)
287           pbsaShort = BiostrucAnnotSetGetByFid(pbsa, Fid, Fsid);
288         else
289           pbsaShort = PruneBiostrucAnnotHits(pbsa, Fsid, pvnFids);
290 
291         if (pbsaShort == NULL) {
292 		printf("Content-type: text/html\n\n");
293 		printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
294 		printf("<h3>Can't find alignment record.</h3>\n");
295 		return 0;
296 	}
297 
298 	if (MMDBInit() == FALSE) {
299 		printf("Content-type: text/html\n\n");
300 		printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
301 		printf("<h3>MMDBInit failed.</h3>\n");
302 		return 0;
303 	}
304 
305         pbsfs = pbsaShort->features;
306 
307         pbsaStruct = BiostrucAlignNew();
308 
309         if (pbsfs)
310         {
311           pbsf = pbsfs->features;
312           szTemp = pbsf->name;
313 	  szName[0] = szTemp[0];
314 	  szName[1] = szTemp[1];
315 	  szName[2] = szTemp[2];
316 	  szName[3] = szTemp[3];
317 	  szName[4] = '\0';
318         }
319 
320         if (JobID == NULL)
321         pbsMaster = FetchBiostrucPDB(szName, complexity, 1);
322         else
323         {
324           AsnName[0]='\0';
325           StringCpy(AsnName, "/b");
326           StringCat(AsnName, szName);
327 
328           AsnPath[0]='\0';
329           StringCpy(AsnPath, VSPATH);
330           StringCat(AsnPath, JobID);
331           StringCat(AsnPath, AsnName);
332 
333           pbsMaster = FetchBS(AsnPath, 0, complexity, 1, POWER_VIEW);
334         }
335 
336         if (pbsMaster == NULL)
337         {
338 	  printf("Content-type: text/html\n\n");
339 	  printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
340 	  printf("<h3> Unable to load master structure.</h3>\n");
341 	  return 0;
342 	}
343 
344         /* Load in Standard Dictionary to make sequences - Ken */
345         aipr = NULL;
346         aipr = AsnIoOpen("bstdt", "rb");
347 
348         if (aipr == NULL)
349         {
350 		printf("Content-type: text/html\n\n");
351 		printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
352 		printf("<h3>Can't find standard dictionary.</h3>\n");
353 		return 0;
354 	}
355 
356         stdDictionary = BiostrucResidueGraphSetAsnRead(aipr, NULL);
357         AsnIoFlush(aipr);
358         aipr = AsnIoClose(aipr);
359 
360        /* retrieve the bioseq for master and put in ValNode */
361        sep = (SeqEntryPtr) MakeBioseqs(pbsMaster, stdDictionary);
362        if ( sep == NULL )
363        {
364          printf("Content-type: text/html\n\n");
365          printf("<h2>VASTSERV Error (VastToCn3d)</h2>\n");
366          printf("<h3>Unable to get SeqEntry.</h3>\n");
367          return 0;
368        }
369        ValNodeLink(&(pbsaStruct->sequences), sep);
370        /* PruneBiostruc if Aligned Chain Options has been chosen */
371        if (Chain)
372        {
373          if (szTemp[4] != ' ')
374          {
375            chain[0] = szTemp[4];
376            chain[1] = '\0';
377            pbsTemp = (BiostrucPtr)PruneBiostruc(pbsMaster, chain);
378            pbsMaster = NULL;
379            pbsMaster = pbsTemp;
380          }
381        }
382 
383         /* Make a linked list of Biostrucs of the slave structures*/
384          while (pbsf)
385          {
386             szTemp = pbsf->name;
387             szName[0] = szTemp[7];
388 	    szName[1] = szTemp[8];
389 	    szName[2] = szTemp[9];
390 	    szName[3] = szTemp[10];
391 	    szName[4] = '\0';
392 
393 	    if (!pbsSlaveHead)
394             {
395                 pbsSlaveHead =  FetchBiostrucPDB(szName, complexity, 1);
396 		if (!pbsSlaveHead)
397                 {
398                   printf("Content-type: text/html\n\n");
399 		  printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
400 		  printf("<h3> Unable to load slave structure.</h3>\n");
401 		  return 0;
402                 }
403                 /* Make Bioseq for Slaves */
404                 sep = (SeqEntryPtr) MakeBioseqs(pbsSlaveHead, stdDictionary);
405                 if ( sep == NULL )
406                 {
407 		  printf("Content-type: text/html\n\n");
408 		  printf("<h2>VASTSERV Error (VastToCn3d)</h2>\n");
409 		  printf("<h3>Unable to get SeqEntry.</h3>\n");
410 		  return 0;
411 	        }
412                 ValNodeLink(&(pbsaStruct->sequences), sep);
413                 /* PruneBiostruc if Aligned Chain Options has been chosen */
414                 if (Chain)
415                 {
416                   if (szTemp[11] != ' ')
417                   {
418                     chain[0] = szTemp[11];
419                     chain[1] = '\0';
420                     pbsTemp = (BiostrucPtr)PruneBiostruc(pbsSlaveHead, chain);
421                     pbsSlaveHead = NULL;
422                     pbsSlaveHead = pbsTemp;
423                   }
424                 }
425                 pbsSlaveTail = pbsSlaveHead;
426 	    }
427             else
428             {
429 		pbsSlave = FetchBiostrucPDB(szName, complexity, 1);
430 		if (!pbsSlave)
431                 {
432                   printf("Content-type: text/html\n\n");
433 		  printf("<h2>VASTSERV Error (VastToCn3D)</h2>\n");
434 		  printf("<h3> Unable to load slave structure.</h3>\n");
435 		  return 0;
436                 }
437 		/* Make Bioseq for Slaves */
438                 sep = (SeqEntryPtr) MakeBioseqs(pbsSlave, stdDictionary);
439                 if ( sep == NULL )
440                 {
441 		  printf("Content-type: text/html\n\n");
442 		  printf("<h2>VASTSERV Error (VastToCn3d)</h2>\n");
443 		  printf("<h3>Unable to get SeqEntry.</h3>\n");
444 		  return 0;
445 	        }
446                 ValNodeLink(&(pbsaStruct->sequences), sep);
447                 /* PruneBiostruc if Aligned Chain Options has been chosen */
448                 if (Chain)
449                 {
450                   if (szTemp[11] != ' ')
451                   {
452                     chain[0] = szTemp[11];
453                     chain[1] = '\0';
454                     pbsTemp = (BiostrucPtr)PruneBiostruc(pbsSlave, chain);
455                     pbsSlave = NULL;
456                     pbsSlave = pbsTemp;
457                   }
458                 }
459                 pbsSlaveTail->next = pbsSlave;
460                 pbsSlaveTail = pbsSlaveTail->next;
461                 pbsSlaveTail->next = NULL;
462             }
463 
464             pbsf = pbsf->next;
465          }
466         /* Make a linked list of sequence alignments of master and slaves */
467         pbsf=pbsfs->features;
468         while (pbsf) {
469           if (!psaAlignHead) {
470             psaAlignHead = fnPBSFtoPSA (pbsf);  /* get the sequence alignments */
471             if (psaAlignHead == NULL || psaAlignHead->data == NULL) {
472 		printf("Content-type: text/html\n\n");
473 		printf("<h2>VASTSERV Error (VastToCn3d)</h2>\n");
474 		printf("<h3>Unable to create SeqAnnot.</h3>\n");
475 		return 0;
476 	    }
477             salpHead = (SeqAlignPtr)(psaAlignHead->data);
478             salpTail = salpHead;
479           }
480           else {
481              psaAlignTail = fnPBSFtoPSA (pbsf);
482              salpTail->next = (SeqAlignPtr)(psaAlignTail->data);
483              if (psaAlignTail == NULL || psaAlignTail->data == NULL) {
484 		printf("Content-type: text/html\n\n");
485 		printf("<h2>VASTSERV Error (VastToCn3d)</h2>\n");
486 		printf("<h3>Unable to create SeqAnnot.</h3>\n");
487 		return 0;
488 	     }
489              salpTail = salpTail->next;
490              salpTail->next = NULL;
491           }
492           pbsf = pbsf->next;
493         }
494 
495   pbsaStruct->master = pbsMaster;
496   pbsaStruct->slaves = pbsSlaveHead;
497   pbsaStruct->alignments = pbsaShort;
498   pbsaStruct->seqalign = psaAlignHead;
499 
500   pvnNcbi = ValNodeNew(NULL);
501   pvnNcbi->choice =  NcbiMimeAsn1_alignstruc;
502   pvnNcbi->data.ptrvalue = pbsaStruct;
503   pvnNcbi = (NcbiMimeAsn1Ptr) CheckId(pvnNcbi, JobID);      /* to check identity, yanli  */
504 
505   OutputFile = stdout;
506 
507   if (iPDB == 0)		/* cn3d MIME */
508     printf ("Content-type: chemical/ncbi-asn1-binary\n\n");
509 
510   else if (iPDB == 1) {		/* "See File" */
511     printf ("Content-type: text/html\n\n");
512     printf ("<HTML><body><pre>\n");
513   }
514 
515   else				/* "Save File" */
516     printf ("Content-type: application/octet-stream\n\n");
517 
518   if (iPDB != 1)
519     paiFile = AsnIoNew(ASNIO_BIN_OUT, stdout, NULL, NULL, NULL);
520 
521   else
522     paiFile = AsnIoNew(ASNIO_TEXT_OUT, stdout, NULL, NULL, NULL);
523 
524   NcbiMimeAsn1AsnWrite(pvnNcbi, paiFile, NULL);
525   AsnIoFlush(paiFile);
526   AsnIoClose(paiFile);
527 
528   CloseMMDBAPI();
529   MMDBFini();
530   VASTFini();
531   return 0;
532 
533 } /* end of VastToCn3D */
534