1 /*   mmdbapi3.c
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *            National Center for Biotechnology Information (NCBI)
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government do not place any restriction on its use or reproduction.
13 *  We would, however, appreciate having the NCBI and the author cited in
14 *  any work or product based on this material
15 *
16 *  Although all reasonable efforts have been taken to ensure the accuracy
17 *  and reliability of the software and data, the NLM and the U.S.
18 *  Government do not and cannot warrant the performance or results that
19 *  may be obtained by using this software or data. The NLM and the U.S.
20 *  Government disclaim all warranties, express or implied, including
21 *  warranties of performance, merchantability or fitness for any particular
22 *  purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name:  mmdbapi3.c
27 *
28 * Author:  Christopher Hogue, Hitomi Ohkawa
29 *
30 * Version Creation Date:   08/06/95
31 *
32 * $Revision: 6.20 $
33 *
34 * File Description: FlatFile Generators for PDB & Kinemage
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date     Name        Description of modification
39 * -------  ----------  -----------------------------------------------------
40 * 08/30/95  C. Hogue    Changed the element & amino acid lookups to functions
41 *                       Fixed ions, hets and x-links in WriteKinAnimate,
42 *                       Moved globals from mmdbapi3.h here, checked over
43 *                       memory usage.
44 *
45 *
46 * $Log: mmdbapi3.c,v $
47 * Revision 6.20  2000/05/19 21:53:37  lewisg
48 * fix header formatting errors
49 *
50 * Revision 6.19  2000/05/15 23:39:33  lewisg
51 * shred cblast, add menu items for gapped/ungapped, fix pdbheaders
52 *
53 * Revision 6.18  2000/05/09 19:51:01  lewisg
54 * add new blast header to file>properties
55 *
56 * Revision 6.17  2000/05/08 20:33:29  lewisg
57 * get rid of fault because vastsrch returns null date
58 *
59 * Revision 6.16  2000/05/08 16:50:47  lewisg
60 * fix formatting bugs in pdb format
61 *
62 * Revision 6.15  2000/05/06 00:05:05  lewisg
63 * rework pdb dumpers to use ncbi data
64 *
65 * Revision 6.14  2000/04/27 22:21:57  lewisg
66 * misc bugs/features
67 *
68 * Revision 6.13  2000/03/31 22:30:47  lewisg
69 * fix output of CONECT, create intrabond traverser, misc bugs
70 *
71 * Revision 6.12  2000/01/31 19:59:12  lewisg
72 * fix output of date in pdb header
73 *
74 * Revision 6.11  2000/01/18 22:49:16  lewisg
75 * send OM_MSG_FLUSH to ddv/udv, tweak CPK coloration, misc bugs
76 *
77 * Revision 6.10  2000/01/14 21:40:39  lewisg
78 * add translucent spheres, ion labels, new cpk, fix misc bugs
79 *
80 * Revision 6.9  1999/12/22 22:49:20  lewisg
81 * fix color bugs: no color in color by domain, selection overrides cpk and temperature
82 *
83 * Revision 6.8  1999/10/06 16:47:47  addess
84 * added line feeds and space filling to END and CONECT reocrds in write pdb function
85 *
86 * Revision 6.7  1998/08/26 18:02:42  kans
87 * fixed -v -fd warnings
88 *
89 * Revision 6.6  1998/06/17 18:01:01  lewisg
90 * orange secondary structure
91 *
92 * Revision 6.5  1998/04/15 12:21:26  kans
93 * needed to include prtutil.h
94 *
95 * Revision 6.4  1998/04/15 00:01:00  lewisg
96 * fixed AuthorListPDB to work on std author names
97 *
98 * Revision 6.3  1998/03/06 23:17:24  lewisg
99 * codewarrior fixes
100 *
101 * Revision 6.2  1998/03/06 01:14:40  lewisg
102 * merge
103 *
104 * Revision 6.1  1997/12/02 16:37:41  lewisg
105 * added %5ld to line 498
106 *
107 * Revision 6.0  1997/08/25 18:11:09  madden
108 * Revision changed to 6.0
109 *
110 * Revision 5.5  1997/02/03 16:35:23  hogue
111 * Changed Traverser in FASTA dumper to traverse when no models.
112 *
113  * Revision 5.4  1997/01/27  21:43:48  hogue
114  * Added Code to write FASTA reports and FASTA files from biopolymer molecules
115  *
116  * Revision 5.3  1996/08/19  21:07:26  vakatov
117  * Removed redundant(and dangerous) function castings to "pNodeFunc"
118  *
119  * Revision 5.2  1996/07/22  16:16:34  hogue
120  * Removed an excess MemFree from WritePDBRemarks.
121  *
122  * Revision 5.1  1996/07/22  00:29:32  hogue
123  * Added a WritePDBRemarks function for PDB file generation.
124  *
125  * Revision 5.0  1996/05/28  14:02:09  ostell
126  * Set to revision 5.0
127  *
128  * Revision 1.23  1996/05/22  20:44:28  hogue
129  * Changed color scheme of hydrophobes from brown to grey.
130  *
131  * Revision 1.22  1996/05/01  21:49:23  hogue
132  * Fixed spacing problem in some PDB files HELIX records.
133  *
134  * Revision 1.21  1996/04/12  20:27:40  hogue
135  * Added AM_POLY cases to Kinemage generators.  Altered the color scheme for structure rendering, added inter-residue bond walking on heterogen rendering passes for polymers.
136  *
137  * Revision 1.20  1996/03/29  19:39:30  hogue
138  * Changed color schemes for NA's, temp factors and sec. structure.
139  *
140  * Revision 1.19  1996/02/28  17:32:12  hogue
141  * Fixes to string literals being altered causing LINUX crashes...
142  *
143  * Revision 1.18  1996/01/31  21:38:35  hogue
144  * Changed PDNSM and kin to PDNML, fixed bugs in Kinemage and PDB file generation given subsets of model lists.
145  *
146  * Revision 1.17  1995/10/12  17:08:57  hogue
147  * Made Au & Hg the right colors.
148  *
149  * Revision 1.16  1995/10/05  17:42:11  hogue
150  * Made Kinemage color tables public
151  *
152  * Revision 1.15  1995/09/21  20:27:35  hogue
153  * Added code for B. Brylawski to make HTML output summary forms.
154  *
155  * Revision 1.14  1995/09/20  14:04:03  hogue
156  * Return value for WriteStrucSummary
157  *
158  * Revision 1.13  1995/09/19  21:08:52  hogue
159  * Added WriteStrucSummary(), Cleaned up Kinemage Text Header.
160  *
161  * Revision 1.12  1995/09/18  21:25:59  hogue
162  * ProgMon() calls, Het names in Kin files, PDB disclaimer added.
163  *
164  * Revision 1.11  1995/09/05  19:12:31  hogue
165  * Separated fn call out of fprintf, fixed for NULL strings, unknown elements.
166  *
167  * Revision 1.10  1995/09/05  15:56:08  hogue
168  * Kinemage Atom-Type rendering Ion fix.
169  *
170  * Revision 1.9  1995/09/05  14:17:42  hogue
171  * Logic fix for multiple vs single Kinemage models
172  *
173  * Revision 1.8  1995/09/01  14:02:09  hogue
174  * NMR multiple model display bug fix.
175  *
176  * Revision 1.7  1995/08/31  18:50:37  hogue
177  * Removed @thinline, <A> Kinemage bugs, Forced NMR animate off if 1 model only.
178  *
179  * Revision 1.6  1995/08/30  19:36:44  kans
180  * numerous changes
181  *
182  * Revision 1.5  1995/08/29  20:45:54  kans
183  * default bKinRender to KIN_VIRTUAL
184  *
185  * Revision 1.4  1995/08/29  20:03:06  kans
186  * Entrez-like loading now enabled, models fixed
187  *
188  * Revision 1.1  1995/08/28  19:30:14  kans
189  * Initial revision
190  *
191 *
192 * ==========================================================================
193 */
194 /*****************************************************************************
195 *
196 *  mmdbapi3.c
197 *
198 *  UNDER CONSTRUCTION NOTICE.
199 *	SUBJECT TO RADICAL CHANGES...
200 *
201 *  programmer C.W.V. Hogue
202 *  created: 6 AUGUST 95
203 *  last mod: 28 AUGUST 95
204 *****************************************************************************/
205 
206 
207 #include <ncbi.h>
208 #include <asn.h>
209 #include <mmdbapi.h>
210 #include <prtutil.h>
211 /*#include <mmdbapi1.h>
212 #include <mmdbapi2.h>
213 #include <mmdbapi3.h> */
214 
215 
216 /* these are declared and initialized in mmdbapi2.c */
217 extern CharPtr NCBIstdaaUC;
218 extern CharPtr NCBI4naUC;
219 extern CharPtr NCBI4naLC;
220 extern CharPtr NCBIstdaaLC;
221 
222 
223 
224 /* numbers are addresses into KineColors */
225 /* this assigns a color to a residue type */
226 Int1 KinAAColor[MAX_NCBIstdaa] = {21,20,11,
227 	9,12,12,3,20,4,20,4,20,9,6,2,6,4,8,8,20,3,20,3,11,10,1 };
228 Int2 KinNAColor[MAX_NCBI4na] = {0,5,7,17,8,2,12,0,6,17,18,0,0,0,0,1};
229 
230 
231 Int1 KinAtoms[MAX_KIN_ATOMS] = {1,6,7,8,15,16};
232 
233 
234 /* this assigns a color to a temperature scale */
235 Int1 ThermKine[KIN_COLOR_THERM] = {4,4,5,6,6,7,8,9,10,11,11,13,1,12,2,0};
236 Int4 TempsKine[KIN_COLOR_THERM] = {0,500,1000,1500,2000,2500,3000,3500,4000,5000,
237 					  6000,7000,8000,9000,10000,99900};
238 
239 
240 
241 /* this assigns a color pair for color-by-molecule number */
242 Int1 ColorNumKinBB[10] = {14,6,8,4,12,5,9,11,12};
243 Int1 ColorNumKinSC[10] = {14,7,18,3,13,17,19,10,14,20};
244 Int1 ColorNumKinAC[10] = {0,1,2,14,17,6,8,4,1};
245 
246 
247 CharPtr KineColors[KIN_COLOR_MAX] = {
248 	"default", /*0*/
249 	"hotpink",
250 	"magenta",
251 	"purple",
252 	"blue",
253 	"sky",   /*5*/
254 	"cyan",
255 	"sea",
256 	"green",
257 	"yellow",
258 	"gold", /*10*/
259 	"orange",
260 	"red",
261 	"pink",
262 	"pinktint",
263 	"white", /*15*/
264 	"black",
265 	"bluetint",
266 	"greentint",
267 	"yellowtint",
268 	"gray", /*20*/
269 	"brown" };
270 
271 Int1 ElementKinColors[MAX_ELEMENTS]  = {
272  	16,
273 	15, /* H */
274 	15, /* He */
275 	15, /* Li */
276 	15, /* Be */
277 	34, /* B */
278 	20, /* C */
279 	17, /* N */
280 	12, /* O */
281 	8, /* F */
282 	34, /* Ne */
283 	36, /* Na */
284 	15, /* Mg */
285 	15, /* Al */
286 	34, /* Si */
287 	11, /* P */
288 	19, /* S */
289 	8, /* Cl */
290 	34, /* Ar */
291 	35, /* K */
292 	15, /* Ca */
293 	15, /* Sc */
294 	15, /* Ti */
295 	15, /* V */
296 	15, /* Cr */
297 	15, /* Mn */
298 	33, /* Fe */
299 	15, /* Co */
300 	15, /* Ni */
301 	4, /* Cu */
302 	15, /* Zn */
303 	15, /* Ga */
304 	34, /* Ge */
305 	34, /* As */
306 	34, /* Se */
307 	21, /* Br */
308 	34, /* Kr */
309 	15, /* Rb */
310 	15, /* Sr */
311 	15, /* Y */
312 	15, /* Zr */
313 	15, /* Nb */
314 	15, /* Mo */
315 	15, /* Tc */
316 	15, /* Ru */
317 	15, /* Rh */
318 	15, /* Pd */
319 	15, /* Ag */
320 	15, /* Cd */
321 	15, /* In */
322 	15, /* Sn */
323 	15, /* Sb */
324 	34, /* Te */
325 	21, /* I */
326 	34, /* Xe */
327 	15, /* Cs */
328 	15, /* Ba */
329 	15, /* La */
330 	15, /* Ce */
331 	15, /* Pr */
332 	15, /* Nd */
333 	15, /* Pm */
334 	15, /* Sm */
335 	15, /* Eu */
336 	15, /* Gd */
337 	15, /* Tb */
338 	15, /* Dy */
339 	15, /* Ho */
340 	15, /* Er */
341 	15, /* Tm */
342 	15, /* Yb */
343 	15, /* Lu */
344 	15, /* Hf */
345 	15, /* Ta */
346 	15, /* W */
347 	15, /* Re */
348 	15, /* Os */
349 	15, /* Ir */
350 	15, /* Pt */
351 	19, /* Au */
352 	15, /* Hg */
353 	15, /* Tl */
354 	15, /* Pb */
355 	15, /* Bi */
356 	1, /*  */
357 	1, /*  */
358 	1, /*  */
359 	1, /*  */
360 	1, /*  */
361 	1, /*  */
362 	1, /*  */
363 	1, /*  */
364 	1, /*  */
365 	1, /*  */
366 	1, /*  */
367 	1, /*  */
368 	1, /*  */
369 	1, /*  */
370 	1, /*  */
371 	1, /*  */
372 	1, /*  */
373 	1, /*  */
374 	1, /*  */
375 	1 /*  */};
376 
377 
MMDB_writeres(Char * pcResNum,Int4 choice)378 static void MMDB_writeres(Char *pcResNum, Int4 choice)
379 {
380     if (choice < 10000)
381         sprintf(pcResNum, "%4d ", choice);
382     else sprintf(pcResNum, "%5d", choice);
383 }
384 
385 
WriteAtomOrHet(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)386 void LIBCALLBACK WriteAtomOrHet(PFB pfbThis, Int4 iModel,  Int4 iIndex,  Pointer ptr)
387 {  /* iIndex used to flag use for constructing ATOM or HETATM (False) records */
388   PMAD pmadThis = NULL;
389   PALD paldThis = NULL;
390   PMGD pmgdThis = NULL;
391   PMMD pmmdThis = NULL;
392   CharPtr pcAlt = NULL;
393   CharPtr pcChem = NULL;
394   CharPtr pcRes = NULL;
395   CharPtr pcTemp = NULL;
396   CharPtr pcResNum = NULL;
397   CharPtr pcChain = NULL;
398   CharPtr pcStruc = NULL;
399   FILE *pFile = NULL;
400   FloatLo fIsotropic = 0.0;
401   if (ptr) pFile = (FILE *) ptr;
402   if (pfbThis->bMe == (Byte) AM_MAD)
403     {
404 	  pmadThis = (PMAD) pfbThis;
405 	  paldThis = GetAtomLocs(pmadThis, iModel);
406 	  if (paldThis) /* make ATOM or HETATOM lines for all locations */
407  	     {
408 	        /* get pointer to parent molecule and graph */
409 		pmgdThis = GetParentGraph((PFB) pmadThis);
410 		if (!pmgdThis) return;
411 		pmmdThis = GetParentMol((PFB) pmadThis);
412 		if (!pmmdThis) return;
413 		if (iIndex)
414 		   switch ((int)pmmdThis->bWhat)
415 		      { case AM_POLY:
416 			case AM_SOL:   /* make HETATMs */
417 			case AM_UNK:
418 			case AM_HET:
419 			case AM_ION:
420 			case AM_WAT:
421 			  return;
422 			default:
423 			;
424 		       }
425 	        else switch ((int)pmmdThis->bWhat)
426 		       {
427 		        case AM_DNA:
428 			case AM_RNA:     /* make ATOMS */
429 			case AM_PROT:
430 			  return;
431 			default:
432 			;
433 		       }
434 
435 		pcResNum = (CharPtr)MemNew((size_t)6*sizeof(char));
436         if(iIndex) MMDB_writeres(pcResNum, pmgdThis->pdnmgLink->choice);
437         else MMDB_writeres(pcResNum, pmmdThis->pdnmmLink->choice);
438 
439  		pcChem = StringSave(pmadThis->pcAName);
440 		if (!pcChem)
441 		  {
442 		    pcChem = StringSave("    ");
443 		    pcTemp = ElementName(pmadThis->pvnmaLink->choice);
444 		    if (pcTemp)
445 		      {
446 			pcChem[1] = pcTemp[0];
447 			if (pcTemp[1] != '\0')
448 			 {
449 			   pcChem[0] = pcTemp[0];
450 			   pcChem[1] = pcTemp[1];
451 			 }
452 		      }
453 		  }
454 		pcTemp = NULL;
455  		pcRes = StringSave(ParentGraphPDBName((PFB) pmadThis));
456 	 	if (!pcRes)
457 		    pcRes = StringSave("UNK");
458 		pcTemp = pcRes;
459 		if ((pmgdThis->bWhat & (Byte) DICT_LOCAL) &&
460 		    ((pcRes[0]=='D') || (pcRes[0]=='R')) &&
461 		    (pcRes[1]=='N') &&
462 		    (pcRes[2]=='A'))
463 		   {
464 		      pcTemp = (CharPtr)&pcRes[3];
465 		   }
466 		if (StringLen(pcTemp) > 3) pcTemp[3] = '\0'; /* truncate SER COOH dict. */
467 		pcChain = ParentMolName((PFB) pmadThis);
468 		if (!pcChain) pcChain = " ";
469 		pcStruc = ParentStrucName((PFB) pmadThis);
470 		if (!pcStruc) pcStruc = "1UNK";
471 		while (paldThis) /* print for each location */
472 		   {
473 
474 		     switch((int)pmmdThis->bWhat)
475 		       {
476 		       	case AM_POLY:
477 			case AM_SOL:
478 			case AM_UNK:
479 			case AM_HET:
480 			case AM_ION:
481 			case AM_WAT:
482 			  fprintf(pFile,"%6s","HETATM");
483 			  fflush(pFile);
484 			  break;
485 		        case AM_DNA:
486 			case AM_RNA:
487 			case AM_PROT:
488 			  fprintf(pFile,"%6s","ATOM  ");
489 			  fflush(pFile);
490 			}
491 		    pcAlt = StringSave(" ");
492 		    pcAlt[0] = paldThis->cAltConf;
493 	            if (paldThis->iFloatNo)
494 			{
495 			  fprintf(pFile,"%5ld %4s%s%3s %1s%5s   %8.3f%8.3f%8.3f",
496 				(long) paldThis->iUniqueId, /* Atom serial No */
497 				pcChem, /* Atom name "cccc" */
498 				pcAlt, /* Alternat loc id char "c" */
499 				pcTemp, /* Res name "ccc" */
500 				pcChain, /* Chain id char "c"*/
501 				pcResNum, /* Residue Sequence String "iiiic" */
502 				(float) paldThis->pflvData[0],
503 				(float) paldThis->pflvData[1],
504 				(float) paldThis->pflvData[2]);
505 			  fflush(pFile);
506 			}
507 		    else
508 			{  /* No locations - use 0.0 so as not to wreck the PDB file */
509 			  fprintf(pFile,"%5ld %4s%s%3s %1s%5s   %8.3f%8.3f%8.3f",
510 				(long) paldThis->iUniqueId, /* Atom serial No */
511 				pcChem, /* Atom name "cccc" */
512 				pcAlt, /* Alternat loc id char "c" */
513 				pcTemp, /* Res name "ccc" */
514 				pcChain, /* Chain id char "c"*/
515 				pcResNum, /* Residue Sequence String "iiiic" */
516 				(float) 0.0,
517 				(float) 0.0,
518 				(float) 0.0);
519 			   fflush(pFile);
520 		    	}
521 		    if (paldThis->iFloatNo >= 3) /* occupancy */
522 			fprintf(pFile,"%6.2f",(float)paldThis->pflvData[3]);
523 		    else
524 			fprintf(pFile, "  1.00");
525 		    fflush(pFile);
526 		    if (paldThis->iFloatNo == 4) /* isotropic temp */
527 		        {
528 			 fprintf(pFile,"%6.2f          %2.2s\n",
529 				 (float)paldThis->pflvData[4],
530 				 ElementName(pmadThis->pvnmaLink->choice));
531 		    	 fflush(pFile);
532 			}
533 		    else
534 		        {
535 	 		 if (paldThis->iFloatNo == 9) /* Anisotropic Temp factors */
536 			   {
537 			      fIsotropic = (FloatLo) (((paldThis->pflvData[4] +
538 						    paldThis->pflvData[5] +
539 						    paldThis->pflvData[6]) / 3) * 10000);
540 			      fprintf(pFile,"%6.2f          %2.2s\n",
541 				 (float)fIsotropic, /* put calculated isotropic */
542 		        	  ElementName(pmadThis->pvnmaLink->choice));  /* finish the ATOM string */
543 			      fflush(pFile);
544 			      fprintf(pFile,"ANISOU%5ld %4s%s%3s %1s%5s  %6d %6d %6d %6d %6d %6d\n",
545 				    (long) paldThis->iUniqueId, /* Atom serial No */
546 				    pcChem, /* Atom name "cccc" */
547 				    pcAlt, /* Alternat loc id char "c" */
548 				    pcRes, /* Res name "ccc" */
549 				    pcChain, /* Chain id char "c"*/
550 				    pcResNum, /* Residue Sequence String "iiiic" */
551 				    (int) (paldThis->pflvData[4] * 10000),
552 				    (int) (paldThis->pflvData[5] * 10000),
553 				    (int) (paldThis->pflvData[6] * 10000),
554 				    (int) (paldThis->pflvData[7] * 10000),
555 				    (int) (paldThis->pflvData[8] * 10000),
556 				    (int) (paldThis->pflvData[9] * 10000));
557 			      fflush(pFile);
558 			   }
559 			 else
560 		           { /* neither temp factors */
561 			      fprintf(pFile,"%6.2f          %2.2s\n",(float)0.0,
562                       ElementName(pmadThis->pvnmaLink->choice));
563 		  	      fflush(pFile);
564 		           }
565 			} /* else from iFloatNo == 4 */
566 
567 		     /* note the future PDB spec has segment id, element and charge
568 		      * at the end
569 		      */
570 
571 		    paldThis = paldThis->next;
572 	           }
573 		 if (pcResNum) MemFree(pcResNum);
574 		 if (pcChem) MemFree(pcChem);
575 		 if (pcRes) MemFree(pcRes);
576 		 if (pcAlt) MemFree(pcAlt);
577 	     }
578       }
579 }
580 
581 
582 
583 
WritePDBModel(Int2 iModel,Int2 iManyModels,PDNMS pdnmsThis,FILE * pFile)584 Int2 LIBCALL WritePDBModel(Int2 iModel, Int2 iManyModels,  PDNMS pdnmsThis, FILE *pFile)
585 {
586    Int2 iTest = 1;
587    Int2 iHold = 0;
588    PMSD pmsdThis = NULL;
589    PDNMM pdnmmThis = NULL;
590    PMMD pmmdThis = NULL;
591    PDNMG pdnmgThis = NULL;
592 
593 
594     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
595     iHold = SetActiveModel(PFBFromDN(pdnmsThis),iModel);
596     if (iManyModels)
597     {
598 	fprintf(pFile, "MODEL     %4d\n", (int)iModel);
599 	fflush(pFile);
600     }
601     pdnmmThis = pmsdThis->pdnmmHead; /* the top of the molecule list */
602     while (pdnmmThis) /* walk the molecules individually */
603       {
604 	ProgMon("Writing PDB");
605 	pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
606 	switch((int)pmmdThis->bWhat)
607 		       {
608 		        case AM_DNA:
609 			case AM_RNA:
610 			case AM_PROT:
611 			  pdnmgThis = pmmdThis->pdnmgHead;
612 			  iTest = TraverseOneModel(pdnmgThis, TRAVERSE_ATOM,
613 			      iModel,  TRUE, (Pointer) pFile,
614                   WriteAtomOrHet); /* make ATOM records */
615 			  fprintf(pFile,"TER\n");
616 			  fflush(pFile);
617 			default:
618 			  ;
619 			}
620 	 pdnmmThis = pdnmmThis->next;
621       }
622     /* get all the Hets in this model */
623     pdnmmThis = pmsdThis->pdnmmHead;
624     iTest = TraverseOneModel(pdnmmThis, TRAVERSE_ATOM, iModel, FALSE, (Pointer) pFile,
625     WriteAtomOrHet); /* make HET records */
626     if (iManyModels)
627 	{
628 	    fprintf(pFile, "ENDMDL\n");
629 	}
630     iHold = SetActiveModel(PFBFromDN(pdnmsThis),iHold);
631     return iTest;
632 }
633 
634 
635 
636 
AuthorListPDB(BiostrucPtr pbsThis)637 CharPtr LIBCALL AuthorListPDB(BiostrucPtr pbsThis)
638 
639 /* this function gives a pretty print list of the authors of the biostruc */
640 
641 {
642 
643    BiostrucDescrPtr pbsdrThis = NULL;
644    BiostrucDescrPtr pbsdrLast = NULL;
645    ValNodePtr pvnPub = NULL;
646    CharPtr pcAuthors = NULL, pcNameString = NULL;
647    CitSubPtr pcsThis = NULL;
648    Boolean bFirst = TRUE;
649    DataVal dvAuthors;
650 
651    pcAuthors = StringSave("");
652    pbsdrThis = ValNodeFindNext(pbsThis->descr,pbsdrLast,BiostrucDescr_attribution);
653    while (pbsdrThis)
654    {
655      pvnPub = (ValNodePtr) pbsdrThis->data.ptrvalue;
656      if (pvnPub->choice == PUB_Sub)
657      {
658        pcsThis = (CitSubPtr) pvnPub->data.ptrvalue;
659        dvAuthors.ptrvalue = pcsThis->authors; /* get the pointer to the author id's */
660        pcNameString = StdAuthListNamesPrint(&dvAuthors);  /* pretty print them */
661        if (pcNameString == NULL) break;
662        pcAuthors = (CharPtr)MemMore( (void *) pcAuthors,(size_t)(StringLen(pcAuthors) +
663          StringLen(pcNameString) + 3 ));  /* reallocate to add room for new authors */
664        if (pcAuthors == NULL) break;
665        if (!bFirst) StringCat(pcAuthors,"\n");   /* add a carriage return in the list */
666        else bFirst = FALSE;
667        StringCat(pcAuthors, pcNameString);
668        MemFree(pcNameString);
669      }
670      pbsdrLast = pbsdrThis;
671      pbsdrThis = ValNodeFindNext(pbsThis->descr,pbsdrLast,BiostrucDescr_attribution);
672    }
673    return pcAuthors;
674 }
675 
676 
677 
WritePDBHeader(PDNMS pdnmsThis,FILE * pFile)678 void LIBCALL WritePDBHeader(PDNMS pdnmsThis,  FILE *pFile)
679 {
680 
681     Int4 i, depyear, depday, depmon, chrcnt, prevcnt, linecnt, back, first, adjust;
682     CharPtr cmpnd, src;
683     Char lastchr, nextchr;
684     Boolean lastok, nextok;
685     PMSD pmsdThis = NULL;
686     BiostrucSourcePtr pbssThis = NULL;
687     BiostrucHistoryPtr pbshThis = NULL;
688     ValNodePtr pvnThis = NULL;
689     ValNodePtr descr;
690     Char orgstring[1024];
691     OrgRefPtr org;
692 
693     if (!pdnmsThis) return;
694     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
695     pvnThis = ValNodeFindNext(pmsdThis->pbsBS->descr,NULL,BiostrucDescr_history);
696     if (pvnThis)
697     {
698         pbshThis = (BiostrucHistoryPtr) pvnThis->data.ptrvalue;
699         pbssThis = pbshThis->data_source;
700     }
701 
702     /* Output a HEADER record. */
703 
704     fprintf(pFile,"HEADER    %s", pmsdThis->pcPdbClass);
705 
706     for (i = 0; i < (40 - StringLen( pmsdThis->pcPdbClass )); i++)
707     {
708         fprintf(pFile," ");
709     }
710     fflush(pFile);
711     if(pbssThis) {
712         depyear = pbssThis->database_entry_date->data[1];
713         depday = pbssThis->database_entry_date->data[3];
714         depmon = pbssThis->database_entry_date->data[2];
715     } else {
716         depyear = depday = 0;
717         depmon = 1;
718     }
719     if (!pmsdThis->pcPDBName) pmsdThis->pcPDBName = StringSave("1UNK");
720 
721     fprintf(pFile,"%2d-%3s-%02d   %s\n",
722         (int) depday,
723         NCBI_months[depmon-1],
724         (int) depyear%100,
725         pmsdThis->pcPDBName);
726 
727     /* Output a COMPND record. */
728 
729     cmpnd = pmsdThis->pcChemName;
730     chrcnt = StringLen(cmpnd);
731     prevcnt = 0;
732 
733     linecnt = 1;
734 
735     while (chrcnt > 0)
736     {
737         fprintf(pFile, "COMPND");
738         back = 0;
739         if (linecnt > 1)
740         {
741             fprintf(pFile,"  %2d ",(int) linecnt++);
742             first = 1;
743         }
744         else
745         {
746             fprintf(pFile,"    ");
747             first = 0;
748             linecnt++;
749         }
750 
751         if (chrcnt > (60-first))
752         {
753             lastchr = cmpnd[prevcnt + 59 - first];
754             nextchr = cmpnd[prevcnt + 59 - first + 1];
755             lastok = (lastchr==' ') || (lastchr=='.') || (lastchr==',') || (lastchr=='\n') || (lastchr=='\t');
756             nextok = (nextchr==' ') || (nextchr=='.') || (nextchr==',') || (nextchr=='\n') || (nextchr=='\t');
757             if (lastok || nextok)
758             {
759                 adjust = 0;
760                 for (i = 0; i < (60-first); i++)
761                 {
762                     if (i==0 && cmpnd[prevcnt]==' ')
763                     {
764                         adjust = 1;
765                         continue;
766                     }
767 
768                     fprintf(pFile,"%c",cmpnd[prevcnt+i]);
769                 }
770 
771                 if (adjust == 1)
772                     fprintf(pFile, " ");
773 
774                 chrcnt = chrcnt - 60 + first;
775                 prevcnt = prevcnt + 60 - first;
776             }
777             else
778             {
779                 i = prevcnt + 59 - first;
780 
781                 do
782                 {
783                     i--;
784                     back++;
785                 }
786                 while ((cmpnd[i]!=' ') && (cmpnd[i]!='.') && (cmpnd[i]!=',') && (i>=0));
787 
788                 adjust = 0;
789                 for (i=0; i<(60-first-back); i++)
790                 {
791                     if (i==0 && cmpnd[prevcnt]==' ')
792                     {
793                         adjust = 1;
794                         continue;
795                     }
796 
797                     fprintf(pFile,"%c",cmpnd[prevcnt+i]);
798                 }
799                 for (i=0; i<(back+adjust); i++)
800                     fprintf(pFile," ");
801 
802                 chrcnt = chrcnt - 60 + first + back;
803                 prevcnt = prevcnt + 60 - first - back;
804             }
805         }
806         else
807         {
808             adjust = 0;
809             for (i=0; i<chrcnt; i++)
810             {
811                 if (i==0 && cmpnd[prevcnt]==' ')
812                 {
813                     adjust = 1;
814                     continue;
815                 }
816 
817                 fprintf(pFile,"%c",cmpnd[prevcnt+i]);
818             }
819 
820             for (i=0; i<(60-first-chrcnt+adjust); i++)
821                 fprintf(pFile," ");
822             chrcnt = 0;
823         }
824         fprintf(pFile,"\n");
825 
826     }
827 
828     /* Output a SOURCE record. */
829 
830     prevcnt = 0;
831     linecnt = 1;
832     orgstring[0] = '\0';
833     org = NULL;
834 
835     for (descr = ((PMMD)(pmsdThis->pdnmmHead->data.ptrvalue))->pMolDescr; descr != NULL; descr = descr->next) {
836         if (descr->choice == BiomolDescr_organism)
837             org = (OrgRefPtr)((BioSourcePtr)descr->data.ptrvalue)->org;
838     }
839 
840     if(org)
841         if(org->common) sprintf(orgstring, "ORGANISM_SCIENTIFIC: %s; ORGANISM_COMMON: %s",
842             org->taxname, org->common);
843         else if (org->taxname) sprintf(orgstring, "ORGANISM_SCIENTIFIC: %s",
844             org->taxname);
845         src = orgstring;
846         chrcnt = StringLen(src);
847 
848         while (chrcnt > 0)
849         {
850             fprintf(pFile, "SOURCE");
851             back = 0;
852 
853             if (linecnt > 1)
854             {
855                 fprintf(pFile,"  %2d ",(int)linecnt++);
856                 first = 1;
857             }
858             else
859             {
860                 fprintf(pFile,"    ");
861                 first = 0;
862                 linecnt++;
863             }
864 
865             if (chrcnt > (60-first))
866             {
867                 lastchr = src[prevcnt + 59 - first];
868                 nextchr = src[prevcnt + 59 - first + 1];
869                 lastok = (lastchr==' ') || (lastchr=='.') || (lastchr==',') || (lastchr=='\n') || (lastchr=='\t');
870                 nextok = (nextchr==' ') || (nextchr=='.') || (nextchr==',') || (nextchr=='\n') || (nextchr=='\t');
871                 if (lastok || nextok)
872                 {
873                     adjust = 0;
874                     for (i = 0; i < (60-first); i++)
875                     {
876                         if (i==0 && src[prevcnt]==' ')
877                         {
878                             adjust = 1;
879                             continue;
880                         }
881 
882                         fprintf(pFile,"%c",src[prevcnt+i]);
883                     }
884 
885                     if (adjust==1)
886                         fprintf(pFile, " ");
887 
888                     chrcnt = chrcnt - 60 + first;
889                     prevcnt = prevcnt + 60 - first;
890                 }
891                 else
892                 {
893                     i = prevcnt + 59 - first;
894 
895                     do
896                     {
897                         i--;
898                         back++;
899                     }
900                     while ((src[i]!=' ') && (src[i]!='.') && (src[i]!=',') && (i>=0));
901 
902                     adjust = 0;
903                     for (i=0; i<(60-first-back); i++)
904                     {
905                         if (i==0 && src[prevcnt]==' ')
906                         {
907                             adjust = 1;
908                             continue;
909                         }
910 
911                         fprintf(pFile,"%c",src[prevcnt+i]);
912                     }
913                     for (i=0; i<(back+adjust); i++)
914                         fprintf(pFile," ");
915 
916                     chrcnt = chrcnt - 60 + first + back;
917                     prevcnt = prevcnt + 60 - first - back;
918                 }
919             }
920             else
921             {
922                 adjust = 0;
923                 for (i=0; i<chrcnt; i++)
924                 {
925                     if (i==0 && src[prevcnt]==' ')
926                     {
927                         adjust = 1;
928                         continue;
929                     }
930 
931                     fprintf(pFile,"%c",src[prevcnt+i]);
932                 }
933 
934                 for (i=0; i<(60-first-chrcnt+adjust); i++)
935                     fprintf(pFile," ");
936 
937                 chrcnt = 0;
938             }
939             fprintf(pFile,"\n");
940 
941         }
942         fflush(pFile);
943         /* output an AUTHOR record */
944         src =  AuthorListPDB(pmsdThis->pbsBS);
945         if (src) chrcnt = StringLen(src);
946         else return;
947 
948         prevcnt = 0;
949         linecnt = 1;
950 
951         while (chrcnt > 0)
952         {
953             fprintf(pFile, "AUTHOR");
954             back = 0;
955 
956             if (linecnt > 1)
957             {
958                 fprintf(pFile,"  %2d ",(int)linecnt++);
959                 first = 1;
960             }
961             else
962             {
963                 fprintf(pFile,"    ");
964                 first = 0;
965                 linecnt++;
966             }
967 
968             if (chrcnt > (60-first))
969 
970             {
971                 lastchr = src[prevcnt + 59 - first];
972                 nextchr = src[prevcnt + 59 - first + 1];
973                 lastok = (lastchr==' ') || (lastchr=='.') || (lastchr==',') || (lastchr=='\n') || (lastchr=='\t');
974                 nextok = (nextchr==' ') || (nextchr=='.') || (nextchr==',') || (nextchr=='\n') || (nextchr=='\t');
975                 if (lastok || nextok)
976                 {
977                     adjust = 0;
978                     for (i = 0; i < (60-first); i++)
979                     {
980                         if (i==0 && src[prevcnt]==' ')
981                         {
982                             adjust = 1;
983                             continue;
984                         }
985 
986                         fprintf(pFile,"%c",src[prevcnt+i]);
987                     }
988 
989                     if (adjust==1)
990                         fprintf(pFile, " ");
991 
992                     chrcnt = chrcnt - 60 + first;
993                     prevcnt = prevcnt + 60 - first;
994                 }
995                 else
996                 {
997                     i = prevcnt + 59 - first;
998 
999                     do
1000                     {
1001                         i--;
1002                         back++;
1003                     }
1004                     while ((src[i]!=' ') && (src[i]!='.') && (src[i]!=',') && (i>=0));
1005 
1006                     adjust = 0;
1007                     for (i=0; i<(60-first-back); i++)
1008                     {
1009                         if (i==0 && src[prevcnt]==' ')
1010                         {
1011                             adjust = 1;
1012                             continue;
1013                         }
1014 
1015                         fprintf(pFile,"%c",src[prevcnt+i]);
1016                     }
1017                     for (i=0; i<(back+adjust); i++)
1018                         fprintf(pFile," ");
1019 
1020                     chrcnt = chrcnt - 60 + first + back;
1021                     prevcnt = prevcnt + 60 - first - back;
1022                 }
1023             }
1024             else
1025             {
1026                 adjust = 0;
1027                 for (i=0; i<chrcnt; i++)
1028                 {
1029                     if (i==0 && src[prevcnt]==' ')
1030                     {
1031                         adjust = 1;
1032                         continue;
1033                     }
1034 
1035                     fprintf(pFile,"%c",src[prevcnt+i]);
1036                 }
1037 
1038                 for (i=0; i<(60-first-chrcnt+adjust); i++)
1039                     fprintf(pFile," ");
1040                 chrcnt = 0;
1041             }
1042             fprintf(pFile,"\n");
1043 
1044         }
1045         fflush(pFile);
1046         if (src) MemFree(src);
1047         return;
1048 }
1049 
1050 
1051 
1052 
1053 
1054 
WritePDBMotifs(PDNMS pdnmsThis,FILE * pFile)1055 void LIBCALL WritePDBMotifs(PDNMS pdnmsThis,  FILE *pFile)
1056 {
1057     CharPtr pcMolnam = NULL;
1058     CharPtr pcResnambeg = NULL;
1059     CharPtr pcResnamend = NULL;
1060     CharPtr pcResnumbeg = NULL;
1061     CharPtr pcResnumend = NULL;
1062     CharPtr pcSSName = NULL;
1063     PMSD pmsdThis = NULL;
1064     PDNMM pdnmmThis = NULL;
1065     PMMD pmmdThis = NULL;
1066     PDNMG pdnmgThis = NULL;
1067     PMGD pmgdThis = NULL;
1068     Int2 iHlxcnt = 0;
1069     Int2 iStcnt = 0;
1070     Int2 iTrncnt = 0;
1071     Boolean bInHelix = FALSE;
1072     Boolean bInSheet = FALSE;
1073     Boolean bInTurn = FALSE;
1074     PMGD pmgdStart = NULL;
1075     PMGD pmgdEnd = NULL;
1076 
1077 
1078     if (!pdnmsThis) return;
1079     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
1080     pdnmmThis = pmsdThis->pdnmmHead; /* the top of the molecule list */
1081 #ifdef _DEBUG_3
1082     printf("Helix scan...\n");
1083 #endif
1084     /* scan for helices */
1085     while (pdnmmThis) /* walk the molecules individually */
1086     {
1087         pmgdEnd = NULL;
1088         pmgdStart = NULL;
1089         pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
1090         if ((int)pmmdThis->bWhat == AM_PROT)
1091         {
1092             bInHelix = FALSE;
1093             pdnmgThis = pmmdThis->pdnmgHead;
1094             while (pdnmgThis)
1095             {
1096                 pmgdThis = (PMGD) pdnmgThis->data.ptrvalue;
1097                 if (pmgdThis->bNCBISecStru & (Byte) SS_HELIX)
1098                 {
1099                     if (bInHelix != TRUE)
1100                     {
1101 #ifdef _DEBUG_3
1102                         printf("Helix found...\n");
1103 #endif
1104                         pmgdStart = pmgdThis;
1105                         bInHelix = TRUE;
1106                     } /* not in a helix */
1107                 } /* this residue is in a helix */
1108                 if ((!(pmgdThis->bNCBISecStru & (Byte) SS_HELIX)) || (pdnmgThis->next == NULL))
1109                 {
1110                     if (bInHelix == TRUE)
1111                     {
1112                         bInHelix =  FALSE;
1113                         if (pmgdStart)
1114                         {
1115 #ifdef _DEBUG_3
1116                             printf("Writing Helix record...\n");
1117 #endif
1118                             if ((pmgdThis->pdnmgLink->last) && (!(pmgdThis->bNCBISecStru & (Byte) SS_HELIX)))
1119                                 pmgdEnd = (PMGD) pmgdThis->pdnmgLink->last->data.ptrvalue;
1120                             if ((pdnmgThis->next == NULL) && (pmgdThis->bNCBISecStru & (Byte) SS_HELIX))
1121                                 pmgdEnd = pmgdThis;
1122                             /* write out the helix record... */
1123                             pcSSName = StringSave("   ");
1124                             if (pmgdStart->pcNCBISS)
1125                             {
1126                                 sprintf(pcSSName, "%3.3s", pmgdStart->pcNCBISS);;
1127                             }
1128                             if (StringLen(pcSSName)> 3) pcSSName[3] = '\0';
1129                             pcResnambeg = StringSave(pmgdStart->pcGraphName);
1130                             if (!pcResnambeg)
1131                                 pcResnambeg = StringSave("UNK");
1132                             if (StringLen(pcResnambeg) > 3) pcResnambeg[3] = '\0';
1133                             pcResnumbeg = StringSave("     ");
1134                             if (pmgdStart->pdnmgLink)
1135                             {
1136                                 MMDB_writeres(pcResnumbeg, pmgdStart->pdnmgLink->choice);
1137                             }
1138 
1139                             pcResnamend = StringSave(pmgdEnd->pcGraphName);
1140                             if (!pcResnamend) pcResnamend = StringSave("UNK");
1141                             if (StringLen(pcResnamend) > 3) pcResnamend[3] = '\0';
1142                             pcResnumend = StringSave("     ");
1143                             if (pmgdEnd->pdnmgLink)
1144                             {
1145                                 MMDB_writeres(pcResnumend, pmgdEnd->pdnmgLink->choice);
1146                             }
1147                             pcMolnam = pmmdThis->pcMolName;
1148                             if (!pcMolnam) pcMolnam = " ";
1149                             fprintf(pFile,  "HELIX  %3d %3s %3s %1s %5s %3s %1s %5s\n",
1150                                 (int) (++iHlxcnt),
1151                                 pcSSName,
1152                                 pcResnambeg,
1153                                 pcMolnam,
1154                                 pcResnumbeg,
1155                                 pcResnamend,
1156                                 pcMolnam,
1157                                 pcResnumend);
1158                             fflush(pFile);
1159                             if (pcResnambeg) MemFree(pcResnambeg);
1160                             if (pcResnumbeg) MemFree(pcResnumbeg);
1161                             if (pcSSName) MemFree(pcSSName);
1162                             if (pcResnamend) MemFree(pcResnamend);
1163                             if (pcResnumend) MemFree(pcResnumend);
1164                             pmgdEnd =  NULL;
1165                             pmgdStart =  NULL;
1166 
1167                         } /* there was a last record */
1168                         else
1169                         { /* reset - some wacky error */
1170                             bInHelix =  FALSE;
1171                             pmgdEnd =  NULL;
1172                             pmgdStart =  NULL;
1173                         }
1174                     } /* helix already started */
1175                 }  /* this res not in a helix */
1176                 pdnmgThis = pdnmgThis->next;
1177             }
1178         } /* if protien */
1179         pdnmmThis = pdnmmThis->next;
1180     } /* next molecule */
1181     pmgdStart = NULL;
1182     pmgdEnd = NULL;
1183     pdnmmThis = pmsdThis->pdnmmHead; /* top of the molecules */
1184     /* scan for sheets */
1185     while (pdnmmThis) /* walk the molecules individually */
1186     {
1187         pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
1188         if ((int)pmmdThis->bWhat == AM_PROT)
1189         {
1190             bInSheet = FALSE;
1191             pdnmgThis = pmmdThis->pdnmgHead;
1192             while (pdnmgThis)
1193             {
1194                 pmgdThis = (PMGD) pdnmgThis->data.ptrvalue;
1195                 if (pmgdThis->bNCBISecStru & (Byte) SS_STRAND)
1196                 {
1197                     if (bInSheet != TRUE)
1198                     {
1199                         pmgdStart = pmgdThis;
1200                         bInSheet = TRUE;
1201                     } /* not in a sheet */
1202                 } /* this residue is in a sheet */
1203                 if ( (!(pmgdThis->bNCBISecStru & (Byte) SS_STRAND))
1204                     || (pdnmgThis->next == NULL))
1205                 {
1206                     if (bInSheet == TRUE)
1207                     {
1208                         bInSheet =  FALSE;
1209                         if (pmgdStart)
1210                         {
1211 #ifdef _DEBUG_3
1212                             printf("Writing sheet record...\n");
1213 #endif
1214                             if ((pmgdThis->pdnmgLink->last) &&
1215                                 (!(pmgdThis->bNCBISecStru & (Byte) SS_STRAND)) )
1216                                 pmgdEnd = (PMGD) pmgdThis->pdnmgLink->last->data.ptrvalue;
1217                             if ((pdnmgThis->next == NULL) &&
1218                                 (pmgdThis->bNCBISecStru & (Byte) SS_STRAND) )
1219                                 pmgdEnd = pmgdThis;
1220 
1221                             /* write out the sheet record... */
1222                             pcSSName = StringSave("   ");
1223                             if (pmgdStart->pcNCBISS)
1224                             {
1225                                 sprintf(pcSSName, "%3.3s", pmgdStart->pcNCBISS);
1226 
1227                             }
1228                             if (StringLen(pcSSName)> 3) pcSSName[3] = '\0';
1229                             pcResnambeg = StringSave(pmgdStart->pcGraphName);
1230                             if (!pcResnambeg)
1231                                 pcResnambeg = StringSave("UNK");
1232                             if (StringLen(pcResnambeg) > 3) pcResnambeg[3] = '\0';
1233                             pcResnumbeg = StringSave("     ");
1234                             if (pmgdStart->pdnmgLink)
1235                             {
1236                                 MMDB_writeres(pcResnumbeg, pmgdStart->pdnmgLink->choice);
1237                             }
1238 
1239                             pcResnamend = StringSave(pmgdEnd->pcGraphName);
1240                             if (!pcResnamend)
1241                                 pcResnamend = StringSave("UNK");
1242                             if (StringLen(pcResnamend) > 3) pcResnamend[3] = '\0';
1243                             pcResnumend = StringSave("     ");
1244                             if (pmgdEnd->pdnmgLink)
1245                             {
1246                                 MMDB_writeres(pcResnumend, pmgdEnd->pdnmgLink->choice);
1247                             }
1248                             pcMolnam = pmmdThis->pcMolName;
1249                             if (!pcMolnam) pcMolnam = " ";
1250                             fprintf(pFile,  "SHEET  %3d %3s%2s %3s %1s%5s %3s %1s%5s\n",
1251                                 (int) (++iStcnt),
1252                                 pcSSName,
1253                                 "  ", /* number of strands in the sheet */
1254                                 pcResnambeg,
1255                                 pcMolnam,
1256                                 pcResnumbeg,
1257                                 pcResnamend,
1258                                 pcMolnam,
1259                                 pcResnumend);
1260                             fflush(pFile);
1261                             if (pcResnambeg) MemFree(pcResnambeg);
1262                             if (pcResnumbeg) MemFree(pcResnumbeg);
1263                             if (pcResnamend) MemFree(pcResnamend);
1264                             if (pcResnumend) MemFree(pcResnumend);
1265                             if (pcResnamend) MemFree(pcSSName);
1266                             pmgdEnd = NULL;
1267                             pmgdStart = NULL;
1268 
1269                         } /* there was a last record */
1270                         else
1271                         { /* reset - some wacky error */
1272                             bInSheet = FALSE;
1273                             pmgdEnd = NULL;
1274                             pmgdStart = NULL;
1275                         }
1276                     } /* sheet already started */
1277                 }  /* this res not in a sheet */
1278                 pdnmgThis = pdnmgThis->next;
1279             }
1280         } /* if protien */
1281         pdnmmThis = pdnmmThis->next;
1282     } /* next molecule */
1283     pmgdStart = NULL;
1284     pmgdEnd = NULL;
1285     pdnmmThis = pmsdThis->pdnmmHead; /* top of the molecules */
1286     /* scan for turns */
1287     while (pdnmmThis) /* walk the molecules individually */
1288     {
1289         pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
1290         if ((int)pmmdThis->bWhat == AM_PROT)
1291         {
1292             bInTurn = FALSE;
1293             pdnmgThis = pmmdThis->pdnmgHead;
1294             while (pdnmgThis)
1295             {
1296                 pmgdThis = (PMGD) pdnmgThis->data.ptrvalue;
1297                 if (pmgdThis->bNCBISecStru & (Byte) SS_TURN)
1298                 {
1299                     if (bInTurn != TRUE)
1300                     {
1301                         pmgdStart = pmgdThis;
1302                         bInTurn = TRUE;
1303                     } /* not in a turn */
1304                 } /* this residue is in a turn */
1305                 if ((!(pmgdThis->bNCBISecStru & (Byte) SS_TURN)) || (pdnmgThis->next == NULL))
1306                 {
1307                     if (bInTurn == TRUE)
1308                     {
1309                         bInTurn =  FALSE;
1310                         if (pmgdStart)
1311                         {
1312 #ifdef _DEBUG_3
1313                             printf("Writing turn record...\n");
1314 #endif
1315                             if ((pmgdThis->pdnmgLink->last) && (!(pmgdThis->bNCBISecStru &(Byte) SS_TURN)))
1316                                 pmgdEnd = (PMGD) pmgdThis->pdnmgLink->last->data.ptrvalue;
1317                             if ((pdnmgThis->next == NULL) &&  (pmgdThis->bNCBISecStru & (Byte) SS_TURN))
1318                                 pmgdEnd = pmgdThis;
1319                             /* write out the turn record... */
1320                             pcSSName = StringSave("   ");
1321                             if (pmgdStart->pcNCBISS)
1322                             {
1323                                 sprintf(pcSSName, "%3.3s", pmgdStart->pcNCBISS);
1324                             }
1325                             if (StringLen(pcSSName)> 3) pcSSName[3] = '\0';
1326                             pcResnambeg = StringSave(pmgdStart->pcGraphName);
1327                             if (!pcResnambeg)
1328                                 pcResnambeg = StringSave("UNK");
1329                             if (StringLen(pcResnambeg) > 3) pcResnambeg[3] = '\0';
1330                             pcResnumbeg = StringSave("     ");
1331                             if (pmgdStart->pdnmgLink)
1332                             {
1333                                 MMDB_writeres(pcResnumbeg, pmgdStart->pdnmgLink->choice);
1334                             }
1335                             pcResnamend = StringSave(pmgdEnd->pcGraphName);
1336                             if (!pcResnamend)
1337                                 pcResnamend = StringSave("UNK");
1338                             if (StringLen(pcResnamend) > 3) pcResnamend[3] = '\0';
1339                             pcResnumend = StringSave("     ");
1340                             if (pmgdEnd->pdnmgLink)
1341                             {
1342                                 MMDB_writeres(pcResnumend, pmgdEnd->pdnmgLink->choice);
1343                             }
1344                             pcMolnam = pmmdThis->pcMolName;
1345                             if (!pcMolnam) pcMolnam = " ";
1346                             fprintf(pFile, "TURN   %3d %3s %3s %1s%5s %3s %1s%5s\n",
1347                                 (int) (++iTrncnt),
1348                                 pcSSName,
1349                                 pcResnambeg,
1350                                 pcMolnam,
1351                                 pcResnumbeg,
1352                                 pcResnamend,
1353                                 pcMolnam,
1354                                 pcResnumend);
1355                             fflush(pFile);
1356                             if (pcResnambeg) MemFree(pcResnambeg);
1357                             if (pcResnumbeg) MemFree(pcResnumbeg);
1358                             if (pcResnamend) MemFree(pcResnamend);
1359                             if (pcResnumend) MemFree(pcResnumend);
1360                             if (pcSSName) MemFree(pcSSName);
1361                             pmgdEnd = NULL;
1362                             pmgdStart = NULL;
1363 
1364                         } /* there was a last record */
1365                         else
1366                         { /* reset - some wacky error */
1367                             bInTurn = FALSE;
1368                             pmgdEnd = NULL;
1369                             pmgdStart = NULL;
1370                         }
1371                     } /* turn already started */
1372                 }  /* this res not in a turn */
1373                 pdnmgThis = pdnmgThis->next;
1374             } /* next graph */
1375         } /* if protien */
1376         pdnmmThis = pdnmmThis->next;
1377     } /* next molecule */
1378     return;
1379 }
1380 
1381 
WritePDBRemarks(PDNMS pdnmsThis,FILE * pFile)1382 void LIBCALL WritePDBRemarks(PDNMS pdnmsThis,  FILE *pFile)
1383 {
1384 
1385    PMSD pmsdThis = NULL;
1386    BiostrucDescrPtr pbsdrThis = NULL;
1387    BiostrucDescrPtr pbsdrLast = NULL;
1388    Char pcThis[81];
1389    int len;
1390 
1391    if (!pdnmsThis) return;
1392    if (!pFile) return;
1393 
1394    pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
1395 
1396    if (!pmsdThis->pbsBS) return;
1397    if (!pmsdThis->pbsBS->descr) return;
1398     fprintf(pFile,"REMARK  00 NCBI PDB FORMAT VERSION 5.0\n");
1399     fprintf(pFile,"REMARK  00 NOTE:  NCBI-MMDB PDB-Format File derived from ASN.1\n");
1400     fprintf(pFile,"REMARK  00 Refer to original ASN.1 file or PDB file for data records\n");
1401     fprintf(pFile,"REMARK  00 not included.  Changes from original PDB files include:\n");
1402     fprintf(pFile,"REMARK  00 - residues are derived by graph matching algorithms.\n");
1403     fprintf(pFile,"REMARK  00 - residue numbers always increase numerically (e.g. no 8A).\n");
1404     fprintf(pFile,"REMARK  00 - taxonomic information reannotated using NCBI Taxonomy.\n");
1405     fprintf(pFile,"REMARK  00 - element names are made consistent.\n");
1406     fprintf(pFile,"REMARK  00 - CONECT records are derived algorithmically.\n");
1407     fprintf(pFile,"REMARK  00 - Secondary structure is derived algorithmically.\n");
1408     fflush(pFile);
1409 #if 0
1410     /* we decided not to print out comments since they may refer to residues that
1411        have been renumbered */
1412     pbsdrThis = ValNodeFindNext(pmsdThis->pbsBS->descr,
1413          pbsdrLast, BiostrucDescr_pdb_comment);
1414     while (pbsdrThis)
1415      {
1416         StringNCpy(pcThis, (CharPtr) pbsdrThis->data.ptrvalue,80);
1417         StringUpper(pcThis);
1418 	len = StringLen(pcThis);
1419 	while (len < 72)
1420 	  {
1421 	      len++;
1422 	      StringCat(pcThis," ");
1423 	  }
1424 	if (pcThis[10] == ':') pcThis[10] = ' ';  /* how'd these horrible colons get there! */
1425         fprintf(pFile,"%s%s\n",pcThis, pmsdThis->pcPDBName);
1426         fflush(pFile);
1427 	pbsdrLast = pbsdrThis;
1428 	pbsdrThis = ValNodeFindNext(pmsdThis->pbsBS->descr,pbsdrLast,
1429                    BiostrucDescr_pdb_comment);
1430      }
1431 #endif /* 0 */
1432   return;
1433 }
1434 
1435 
WritePDBSeqRes(PDNMS pdnmsThis,FILE * pFile)1436 void LIBCALL WritePDBSeqRes(PDNMS pdnmsThis,  FILE *pFile)
1437 {
1438    Int4 resnum,linecnt,rest,curResCnt,i;
1439    CharPtr resnam = NULL;
1440    PDNMG pdnmgRes = NULL;
1441    PMSD pmsdThis = NULL;
1442    PDNMM pdnmmThis = NULL;
1443    PMMD pmmdThis = NULL;
1444    PMGD pmgdThis = NULL;
1445 
1446 
1447     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
1448     pdnmmThis = pmsdThis->pdnmmHead; /* the top of the molecule list */
1449 
1450     while (pdnmmThis) /* walk the molecules individually */
1451       {
1452 	pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
1453 	switch((int)pmmdThis->bWhat)
1454 	 {
1455 	  case AM_DNA:
1456 	  case AM_RNA:
1457 	  case AM_PROT:
1458 		resnum = pmmdThis->iResCount;
1459 		linecnt = 1;
1460  	 	rest = resnum;
1461 	 	pdnmgRes = pmmdThis->pdnmgHead;
1462 	 	while ((rest > 0) && (pdnmgRes != NULL))
1463 	 	  {
1464 	    		fprintf(pFile,"SEQRES  %2d %s %4d  ",
1465 				(int) linecnt,
1466 				pmmdThis->pcMolName,
1467 				(int)resnum);
1468 			fflush(pFile);
1469 			linecnt++;
1470 			if (rest > 13)
1471 	       		    curResCnt = 13;
1472 			else
1473 			    curResCnt = rest;
1474 			i = 0;
1475 			while ((i < curResCnt) && (pdnmgRes != NULL))
1476 			 {
1477 			    pmgdThis = (PMGD) pdnmgRes->data.ptrvalue;
1478 			    resnam = StringSave(pmgdThis->pcGraphName);
1479 			    if (!resnam)
1480 				resnam = StringSave("UNK");
1481 			    if ((pmgdThis->bWhat & (Byte) DICT_LOCAL) &&
1482 			        ((resnam[0]=='D') || (resnam[0]=='R')) &&
1483 				(resnam[1]=='N') &&
1484 				(resnam[2]=='A'))
1485 				{
1486 				    fprintf(pFile,"%3s ",(CharPtr)&resnam[3]);
1487 				    fflush(pFile);
1488 				}
1489 			    else
1490 			        {
1491 				    if (StringLen(resnam) > 3) resnam[3] = '\0';
1492 					/* truncate SER COOH dict. */
1493 				    fprintf(pFile,"%3s ",resnam);
1494 				    fflush(pFile);
1495 				}
1496 			    if (resnam) MemFree(resnam);
1497 			    i++;
1498 			    pdnmgRes = pdnmgRes->next;
1499 			  }
1500 			rest -= curResCnt;
1501             fprintf(pFile,"\n");
1502 			fflush(pFile);
1503 		  } /* while pdnmgRes */
1504 		break;
1505 	  default:
1506 	    ;
1507 	 } /* switch */
1508 	 pdnmmThis = pdnmmThis->next;
1509       } /* while pdnmmThis */
1510     return;
1511 }
1512 
1513 
1514 
1515 
PDBConnect(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)1516 void LIBCALLBACK PDBConnect(PFB pfbThis, Int4 iModel, Int4 iIndex, Pointer ptr)
1517 {
1518 /* when iIndex == 1 it looks for HETs */
1519 /* when iIndex == 0 it does all bonds it encounters */
1520 /* FALSE used with TraverseIBonds  */
1521   PMBD pmbdThis = NULL;
1522   PMMD pmmdFrom = NULL;
1523   PMMD pmmdTo = NULL;
1524   PALD paldFrom = NULL;
1525   PMLD pmldThis = NULL;
1526   PALD paldTo = NULL;
1527   PMSD pmsdThis = NULL;
1528   PDNML pdnmlThis = NULL;
1529   FILE *pFile = NULL;
1530   CharPtr pcThis = NULL;
1531   if (ptr) pFile = (FILE *) ptr;
1532   else return;
1533   if (pfbThis->bMe == (Byte) AM_MBD)
1534       {
1535 	  pmbdThis = (PMBD) pfbThis;
1536 	  pmmdFrom = (GetParentMol((PFB) pmbdThis->pmadFrom));
1537 	  pmmdTo = (GetParentMol((PFB) pmbdThis->pmadTo));
1538 	  if (iIndex == 1)  /* do the HETS only */
1539 	   {
1540 	    if (!
1541 	        ((pmmdFrom->bWhat == (Byte) AM_HET) ||
1542                  (pmmdFrom->bWhat == (Byte) AM_POLY) ||
1543 		(pmmdFrom->bWhat == (Byte) AM_SOL) ||
1544 		(pmmdFrom->bWhat == (Byte) AM_ION) ||
1545 		(pmmdFrom->bWhat == (Byte) AM_WAT) ||
1546 		(pmmdTo->bWhat == (Byte) AM_HET) ||
1547                 (pmmdTo->bWhat == (Byte) AM_POLY) ||
1548 		(pmmdTo->bWhat == (Byte) AM_SOL) ||
1549 		(pmmdTo->bWhat == (Byte) AM_WAT) ||
1550 		(pmmdTo->bWhat == (Byte) AM_ION)) ) return;
1551 	   }
1552       /* get rid of solvent solvent bonds */
1553       if((pmmdFrom->bWhat == (Byte) AM_SOL || pmmdFrom->bWhat == (Byte) AM_WAT)
1554           && (pmmdFrom->bWhat == (Byte) AM_SOL || pmmdFrom->bWhat == (Byte) AM_WAT)) return;
1555 	  if (iIndex == 0) /* don't connect the backbone stupid */
1556 	    {
1557   	     if ((pmbdThis->pmadFrom->bWhat & (Byte) AM_BACKBONE) ||
1558 	         (pmbdThis->pmadTo->bWhat & (Byte) AM_BACKBONE))
1559 		  {
1560 		       return;
1561 		  }
1562 	    }
1563 	  pmsdThis = ToMSDParent(pfbThis);
1564 	  pdnmlThis = DValNodeFindNext(pmsdThis->pdnmlModels, NULL, iModel); /* find the model */
1565  	  if (pdnmlThis)
1566    	    {  /* this connects all alternative conformers recorded */
1567 	      pmldThis = (PMLD) pdnmlThis->data.ptrvalue;
1568 	      pcThis = pmldThis->pcAltConf;
1569 	      if (pcThis)
1570 	      while (StringLen(pcThis))
1571 	        {
1572 		     paldFrom = GetLocation(GetAtomLocs(pmbdThis->pmadFrom, iModel), 0, (Char) pcThis[0]);
1573 		     paldTo = GetLocation(GetAtomLocs(pmbdThis->pmadTo, iModel), 0, (Char) pcThis[0] );
1574 		     if (paldFrom && paldTo)
1575 			{  /* only does the first one in a model */
1576 			    /* have to match up above stuff */
1577 			    fprintf(pFile, "CONECT%5ld%5ld                  \n",
1578 				(long) paldFrom->iUniqueId,
1579 				(long) paldTo->iUniqueId);
1580 			    fflush(pFile);
1581 			}
1582 		    paldFrom = NULL;
1583 		    paldTo = NULL;
1584 		    pcThis = (CharPtr) &pcThis[1];
1585 		}
1586 	     else
1587   		{
1588 		     paldFrom = GetLocation(GetAtomLocs(pmbdThis->pmadFrom, iModel), 0, ' ');
1589 		     paldTo = GetLocation(GetAtomLocs(pmbdThis->pmadTo, iModel), 0, ' ');
1590 		     if (paldFrom && paldTo)
1591 			{  /* only does the first one in a model */
1592 			    /* have to match up above stuff */
1593 			    fprintf(pFile, "CONECT%5ld%5ld                  \n",
1594 				(long) paldFrom->iUniqueId,
1595 				(long) paldTo->iUniqueId);
1596 			    fflush(pFile);
1597 			}
1598 		}
1599 
1600 	    } /* does the model have a location? */
1601     }
1602 }
1603 
1604 
1605 
1606 
WritePDBConnect(PDNMS pdnmsThis,Int2 iModel,FILE * pFile)1607 void LIBCALL WritePDBConnect(PDNMS pdnmsThis,  Int2 iModel, FILE *pFile)
1608 {
1609 
1610    Int2 iTest;
1611    /* inter-res and inter-molecule bond pass */
1612    iTest = TraverseOneModel(pdnmsThis, TRAVERSE_IBOND, iModel,
1613          0, pFile, PDBConnect);
1614 
1615   /* HET pass */
1616    iTest = TraverseOneModel(pdnmsThis, TRAVERSE_INTRABOND, iModel,
1617          1, pFile,  PDBConnect);
1618    return;
1619 }
1620 
1621 
1622 
WritePDBModelList(PDNMS pdnmsThis,FILE * pFile,Int2 iNumModels,Int2Ptr i2Vec)1623 Int2 LIBCALL WritePDBModelList(PDNMS pdnmsThis,  FILE *pFile,  Int2 iNumModels,  Int2Ptr i2Vec )
1624 {
1625     Int4 iCount;
1626     Int2 iIndex;
1627     Int2 iTest;
1628     Int2 iManyModels = TRUE;
1629     iCount = AssignAtomLocId(pdnmsThis);  /* !!!MOVE THESE OUT TO WRAPPER */
1630     AssignBackBone(pdnmsThis);
1631 	/* printf("Location count = %ld\n", (long) iCount); */
1632     ProgMon("Writing PDB");
1633     WritePDBHeader(pdnmsThis, pFile);
1634     ProgMon("Writing PDB");
1635     WritePDBRemarks(pdnmsThis, pFile);
1636     WritePDBSeqRes(pdnmsThis, pFile);
1637     WritePDBMotifs(pdnmsThis, pFile);
1638     if (iNumModels == 1) iManyModels = FALSE;
1639     for (iIndex = 0; iIndex < iNumModels; iIndex++)
1640        {
1641 	   ProgMon("Writing PDB");
1642 	   iTest = WritePDBModel(i2Vec[iIndex], iManyModels,  pdnmsThis, pFile);
1643 	   if (!iTest) return 0;
1644        }
1645     for (iIndex = 0; iIndex < iNumModels; iIndex++)
1646        {
1647 	   WritePDBConnect(pdnmsThis, i2Vec[iIndex], pFile);
1648        }
1649     fprintf(pFile, "END\n");
1650     fflush(pFile);
1651     return 1;
1652 }
1653 
1654 
WritePDBOneModel(PDNMS pdnmsThis,FILE * pFile,Int2 iModel)1655 Int2 LIBCALL WritePDBOneModel(PDNMS pdnmsThis,  FILE *pFile,  Int2 iModel)
1656 {
1657     Int2 iRet = FALSE;
1658     iRet = WritePDBModelList(pdnmsThis, pFile, 1, (Int2Ptr) &iModel);
1659     return iRet;
1660 }
1661 
WritePDBAllModel(PDNMS pdnmsThis,FILE * pFile)1662 Int2 LIBCALL WritePDBAllModel(PDNMS pdnmsThis,  FILE *pFile)
1663 {
1664     Int2Ptr i2Vec = NULL;
1665     PDNML pdnmlThis = NULL;
1666     PMLD pmldThis = NULL;
1667     PMSD pmsdThis = NULL;
1668     Int2 iCount = 0;
1669     Int2 iRet = FALSE;
1670 
1671     pmsdThis = (PMSD)  PFBFromDN(pdnmsThis);
1672     if (!(pmsdThis->bMe == (Byte) AM_MSD)) return iRet;
1673 
1674     pdnmlThis = pmsdThis->pdnmlModels; /* the linked-list of models */
1675     if (pdnmlThis)
1676       while (pdnmlThis)
1677        {
1678 	 pmldThis = (PMLD) pdnmlThis->data.ptrvalue;
1679 	 if (pmldThis)
1680  	 if (pmldThis->iType != Model_type_ncbi_vector)
1681 	   {
1682          	iCount++;
1683            }
1684 	 pdnmlThis = pdnmlThis->next;
1685 
1686        }
1687     else return 0;  /* no models */
1688     i2Vec = I2Vector(0, iCount);
1689     if (!i2Vec) return iRet;
1690     iCount = 0;
1691     pdnmlThis = pmsdThis->pdnmlModels;
1692     while (pdnmlThis)
1693 	{  /* copy the model id's into the vector */
1694 	   pmldThis = (PMLD) pdnmlThis->data.ptrvalue;
1695 	   if (pmldThis)
1696  	   if (pmldThis->iType != Model_type_ncbi_vector) /* keep out vector models */
1697 	     {
1698      	  	i2Vec[iCount] = pdnmlThis->choice;
1699 	    	iCount++;
1700 	     }
1701 	    pdnmlThis = pdnmlThis->next;
1702 	}
1703     iRet = WritePDBModelList(pdnmsThis, pFile, iCount, i2Vec);
1704     I2VectorFree(i2Vec, 0);
1705     return iRet;
1706 
1707 }
1708 
1709 
1710 
1711 
1712 
1713 /**************/
1714 /* Kinemage   */
1715 /**************/
1716 
GetKinMolName(PMMD pmmdThis)1717 CharPtr LIBCALL GetKinMolName(PMMD pmmdThis)
1718 {
1719   CharPtr rsult = "mol";
1720 
1721   switch ((int) pmmdThis->bWhat)
1722 	    {
1723 	      case AM_RNA:
1724 	         return "rna";
1725  	      case AM_DNA:
1726 	         return "dna";
1727   	      case AM_PROT:
1728 	         return "pep";
1729  	      case AM_HET:
1730               case AM_POLY:
1731 	        return "het";
1732  	      case AM_ION:
1733 	        return "ion";
1734  	      default:
1735 	        rsult = "mol";
1736 	    }
1737   return rsult;
1738 }
1739 
1740 
1741 
1742 
1743 
1744 
1745 
1746 
1747 
WriteKinSeq(PDNMS pdnmsThis,FILE * pFile)1748 CharPtr LIBCALL WriteKinSeq(PDNMS pdnmsThis,  FILE *pFile)
1749 {  /* writes out the sequence and also generates the composition string  */
1750    Int4 resnum,linecnt,rest,curResCnt,i;
1751    CharPtr resnam;
1752    PDNMG pdnmgRes;
1753    PMSD pmsdThis = NULL;
1754    PDNMM pdnmmThis = NULL;
1755    PMMD pmmdThis = NULL;
1756    PMGD pmgdThis = NULL;
1757    CharPtr pcComposition = NULL;
1758    CharPtr pcKinMolName = NULL;
1759    CharPtr pcTest = NULL;
1760    CharPtr pcComp = NULL;
1761    Int4 iLen = 0;
1762 
1763     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
1764     pdnmmThis = pmsdThis->pdnmmHead; /* the top of the molecule list */
1765     pcComposition = (CharPtr)MemNew((size_t) (MAX_NCBIstdaa + MAX_NCBI4na + 2));
1766     pcComposition[0] = '\0';
1767     fprintf(pFile, "\nSequence(s) as they appear in the PDB file.\n");
1768     fflush(pFile);
1769     while (pdnmmThis) /* walk the molecules individually */
1770       {
1771 	pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
1772 	switch((int)pmmdThis->bWhat)
1773 	 {
1774 	  case AM_HET:
1775                 pdnmgRes = pmmdThis->pdnmgHead;
1776 		pmgdThis = (PMGD) pdnmgRes->data.ptrvalue;
1777 		if (pmgdThis->pcPDBComment)
1778 		  {
1779 		    fprintf(pFile,"\nHeterogen {%d het} Name: %s\n",
1780 				(int)pdnmmThis->choice,
1781 				pmgdThis->pcPDBComment);
1782 		  }
1783 	        break;
1784          case AM_POLY:
1785 	        pdnmgRes = pmmdThis->pdnmgHead;
1786 		pmgdThis = (PMGD) pdnmgRes->data.ptrvalue;
1787 		if (pmgdThis->pcPDBComment)
1788 		  {
1789 		    fprintf(pFile,"\nBiopolymer {%d het} Name: %s\n",
1790 				(int)pdnmmThis->choice,
1791 				pmgdThis->pcPDBComment);
1792 		  }
1793 	        break;
1794 	  case AM_DNA:
1795 	  case AM_RNA:
1796          case AM_PROT:
1797 		resnum = pmmdThis->iResCount;
1798 		linecnt = 1;
1799  	 	rest = resnum;
1800 	 	pdnmgRes = pmmdThis->pdnmgHead;
1801 	        pcKinMolName = GetKinMolName(pmmdThis);
1802 		fprintf(pFile,"\nSequence {%d %s %s} has %d residues:\n",
1803 				(int)pdnmmThis->choice,
1804 				pcKinMolName,
1805 				pmmdThis->pcMolName,
1806 				(int)resnum);
1807 
1808 			fflush(pFile);
1809 	 	while ((rest > 0) && (pdnmgRes != NULL))
1810 	 	  {
1811 
1812 			linecnt++;
1813 			if (rest > 10)
1814 	       		    curResCnt = 10;
1815 			else
1816 			    curResCnt = rest;
1817 			i = 0;
1818 			while ((i < curResCnt) && (pdnmgRes != NULL))
1819 			 {
1820 			    pmgdThis = (PMGD) pdnmgRes->data.ptrvalue;
1821 			    resnam = StringSave(pmgdThis->pcGraphName);
1822 			    if (!resnam)
1823 				resnam = StringSave("UNK");
1824 			    pcTest = NULL;
1825 			    if (pmgdThis->bWhat & (Byte) RES_AA)
1826   			     {
1827 				pcTest = StringChr(NCBIstdaaUC,pmgdThis->pcIUPAC[0]);
1828 
1829 			     }
1830 			    if ((pmgdThis->bWhat & (Byte) RES_RNA) || (pmgdThis->bWhat & (Byte) RES_DNA))
1831 			     {
1832 				pcTest = StringChr(NCBI4naUC,pmgdThis->pcIUPAC[0]);
1833 				if (pcTest)
1834 				  {
1835 				      pcComp = NCBI4naUC;
1836 				      iLen = 0;
1837 				      while ((pcComp != pcTest) && (pcComp))
1838 				        {
1839 					    iLen++;
1840 					    pcComp = (CharPtr) &pcComp[1];
1841 					}
1842 				      pcTest = (CharPtr) &NCBI4naLC[iLen];
1843 				  }
1844 			     }
1845 			    if (!pcTest) pcTest = "?";
1846 			    if (!StringChr(pcComposition, pcTest[0]))
1847 			        {
1848 				  StringNCat(pcComposition, pcTest, 1);
1849 #ifdef _DEBUG_4
1850 printf("%s\n", pcComposition);
1851 #endif
1852 			        }
1853 		            if ((pmgdThis->bWhat & (Byte) DICT_LOCAL) &&
1854 			        ((resnam[0]=='D') || (resnam[0]=='R')) &&
1855 				(resnam[1]=='N') &&
1856 				(resnam[2]=='A'))
1857 				{
1858 				    fprintf(pFile,"%3s ",(CharPtr)&resnam[3]);
1859 				    fflush(pFile);
1860 				}
1861 			    else
1862 			        {
1863 				    if (StringLen(resnam) > 3) resnam[3] = '\0';
1864 					/* truncate SER COOH dict. */
1865 				    fprintf(pFile,"%3s ",resnam);
1866 				    fflush(pFile);
1867 				}
1868 			    if (resnam) MemFree(resnam);
1869 			    i++;
1870 			    pdnmgRes = pdnmgRes->next;
1871 			  }
1872 			rest -= curResCnt;
1873  			fprintf(pFile," \n");
1874 			fflush(pFile);
1875 		  } /* while pdnmgRes */
1876 		break;
1877 	  default:
1878 	    ;
1879 	 } /* switch */
1880 	 pdnmmThis = pdnmmThis->next;
1881       } /* while pdnmmThis */
1882     return pcComposition;
1883 }
1884 
1885 
WriteKinHeader(PDNMS pdnmsThis,FILE * pFile)1886 void LIBCALL WriteKinHeader(PDNMS pdnmsThis,  FILE *pFile)
1887 {
1888 
1889    Int4 depyear, depday;
1890    PMSD pmsdThis = NULL;
1891    BiostrucSourcePtr pbssThis = NULL;
1892    ValNodePtr pvnThis = NULL;
1893    BiostrucHistoryPtr pbshThis = NULL;
1894    CharPtr pcAuthors = NULL;
1895 
1896    if (!pdnmsThis) return;
1897    pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
1898    pvnThis = ValNodeFindNext(pmsdThis->pbsBS->descr,NULL,BiostrucDescr_history);
1899    if (pvnThis)
1900      {
1901       pbshThis = (BiostrucHistoryPtr) pvnThis->data.ptrvalue;
1902       pbssThis = pbshThis->data_source;
1903      }
1904    if (!pmsdThis->pcPDBName) pmsdThis->pcPDBName = StringSave("1UNK");
1905    fprintf(pFile,"Structure Summary\n\n");
1906    fprintf(pFile,"Contents:\n%s\n\n", pmsdThis->pcChemName);
1907    fflush(pFile);
1908    fprintf(pFile,"MMDB Accession:\n%ld\n\n", (long) pmsdThis->iMMDBid);
1909    fprintf(pFile,"PDB Accession:\n%s\n\n", pmsdThis->pcPDBName);
1910    fflush(pFile);
1911    if (pbssThis)
1912      {
1913    	depyear = pbssThis->database_entry_date->data[1];
1914    	depday = pbssThis->database_entry_date->data[3];
1915     if(pbssThis->database_entry_date->data[2] >= 1)
1916    	fprintf(pFile,"PDB Deposition:\n%2d-%3s-%02d\n\n",
1917                    (int) depday,
1918                    NCBI_months[pbssThis->database_entry_date->data[2]-1],
1919                    (int) depyear%100);
1920      }
1921   fprintf(pFile,"Class:\n%s\n\n", pmsdThis->pcPdbClass);
1922   fflush(pFile);
1923   fprintf(pFile,"Source:\n%s\n\n", pmsdThis->pcPdbSource);
1924   fflush(pFile);
1925   pcAuthors =  AuthorListPDB(pmsdThis->pbsBS) ;
1926   if (pcAuthors)
1927     {
1928       fprintf(pFile,"Authors:\n%s\n\n", (CharPtr) &pcAuthors[1]);
1929       fflush(pFile);
1930       MemFree(pcAuthors);
1931     }
1932 
1933   return;
1934 }
1935 
1936 
1937 
1938 
AddLineKin(FILE * pFile,PALD paldFrom,PALD paldTo)1939 void LIBCALL AddLineKin(FILE *pFile,  PALD paldFrom,  PALD paldTo)
1940 {
1941    CharPtr pcAtomFrom = NULL;
1942    CharPtr pcAtomTo = NULL;
1943    CharPtr pcGraphFrom = NULL;
1944    CharPtr pcGraphTo = NULL;
1945    CharPtr pcTempFrom = NULL;
1946    CharPtr pcTempTo = NULL;
1947    PMGD pmgdFrom = NULL;
1948    PMGD pmgdTo = NULL;
1949    PMAD pmadFrom = NULL;
1950    PMAD pmadTo = NULL;
1951 
1952    pmadFrom = (PMAD) paldFrom->pfbParent;
1953    pmadTo = (PMAD) paldTo->pfbParent;
1954    if ((!pmadFrom) || (!pmadTo)) return;
1955    pcAtomFrom = StringSave(pmadFrom->pcAName);
1956    if (!pcAtomFrom)
1957      pcAtomFrom = StringSave(ElementName((Int1)pmadFrom->pvnmaLink->choice));
1958    pcAtomTo = StringSave(pmadTo->pcAName);
1959    if (!pcAtomTo)
1960      pcAtomTo = StringSave(ElementName((Int1)pmadTo->pvnmaLink->choice));
1961    pcTempFrom = StringSave(ParentGraphPDBName((PFB)pmadFrom));
1962    if (!pcTempFrom)
1963 	pcTempFrom = StringSave("UNK");
1964    pmgdFrom = GetParentGraph((PFB)pmadFrom);
1965    pcGraphFrom = pcTempFrom;
1966    if (pmgdFrom)
1967    if ((pmgdFrom->bWhat & (Byte) DICT_LOCAL) &&
1968        ((pcTempFrom[0]=='D') || (pcTempFrom[0]=='R')) &&
1969        (pcTempFrom[1]=='N') &&
1970        (pcTempFrom[2]=='A'))
1971      {
1972        pcGraphFrom = (CharPtr)&pcTempFrom[3];
1973      }
1974    if (StringLen(pcGraphFrom) > 3) pcGraphFrom[3] = '\0'; /* truncate SER COOH dict. */
1975 
1976    pcTempTo= StringSave(ParentGraphPDBName((PFB)pmadTo));
1977    if (!pcTempTo)
1978 	pcTempTo = StringSave("UNK");
1979    pmgdTo = GetParentGraph((PFB)pmadTo);
1980    pcGraphTo = pcTempTo;
1981    if (pmgdTo)
1982    if ((pmgdTo->bWhat & (Byte) DICT_LOCAL) &&
1983        ((pcTempTo[0]=='D') || (pcTempTo[0]=='R')) &&
1984        (pcTempTo[1]=='N') &&
1985        (pcTempTo[2]=='A'))
1986      {
1987        pcGraphTo = (CharPtr)&pcTempTo[3];
1988      }
1989    if (StringLen(pcGraphTo) > 3) pcGraphTo[3] = '\0'; /* truncate SER COOH dict. */
1990 
1991    fprintf(pFile,"{%s %s %d} P%8.3f,%8.3f,%8.3f {%s %s %d} L%8.3f,%8.3f,%8.3f\n",
1992 		    pcAtomFrom,
1993 		    pcGraphFrom,
1994 		    (int) IndexFromNode((PFB)pmgdFrom),
1995 		    (float) paldFrom->pflvData[0],
1996 		    (float) paldFrom->pflvData[1],
1997 		    (float) paldFrom->pflvData[2],
1998 		    pcAtomTo,
1999 		    pcGraphTo,
2000 		    (int) IndexFromNode((PFB)pmgdTo),
2001 		    (float) paldTo->pflvData[0],
2002 		    (float) paldTo->pflvData[1],
2003 		    (float) paldTo->pflvData[2]);
2004    fflush(pFile);
2005    if (pcAtomFrom) MemFree(pcAtomFrom);
2006    if (pcAtomTo) MemFree(pcAtomTo);
2007    if (pcTempTo) MemFree(pcTempTo);
2008    if (pcTempFrom) MemFree(pcTempFrom);
2009    return;
2010 }
2011 
2012 
WriteKinVirt(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)2013 void LIBCALLBACK WriteKinVirt(PFB pfbThis, Int4 iModel,  Int4 iIndex, Pointer ptr)
2014 {
2015 
2016   PMBD pmbdThis = NULL;
2017   PALD paldFrom = NULL;
2018   PALD paldTo = NULL;
2019   FILE *pFile = NULL;
2020 
2021   if (!pfbThis) return;
2022   if (ptr) pFile = (FILE *) ptr;
2023   if (pfbThis->bMe == (Byte) AM_MBD)
2024       {
2025         pmbdThis = (PMBD) pfbThis;
2026 	if (!(pmbdThis->bWhat & (Byte) BOND_VIRTUAL)) return;
2027 	paldFrom = GetLocation(GetAtomLocs(pmbdThis->pmadFrom, iModel), 0, ' ');
2028 	paldTo = GetLocation(GetAtomLocs(pmbdThis->pmadTo, iModel), 0, ' ');
2029 	 if (paldFrom && paldTo)
2030 	    {
2031               AddLineKin(pFile, paldFrom, paldTo);
2032            }
2033       }
2034   return;
2035 }
2036 
WriteKinHet(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)2037 void LIBCALLBACK WriteKinHet(PFB pfbThis, Int4 iModel,  Int4 iIndex, Pointer ptr)
2038 {
2039 
2040   PMBD pmbdThis = NULL;
2041   PALD paldFrom = NULL;
2042   PMMD pmmdFrom = NULL;
2043   PMMD pmmdTo = NULL;
2044   PALD paldTo = NULL;
2045   FILE *pFile = NULL;
2046 
2047 
2048   if (!pfbThis) return;
2049   if (ptr) pFile = (FILE *) ptr;
2050     else return;
2051   if (pfbThis->bMe == (Byte) AM_MBD)
2052       {
2053         pmbdThis = (PMBD) pfbThis;
2054 	pmmdFrom = GetParentMol((PFB)pmbdThis->pmadFrom);
2055 	pmmdTo = GetParentMol((PFB)pmbdThis->pmadTo);
2056 	if (!((pmmdFrom->bWhat & (Byte) AM_HET) ||
2057 	   (pmmdFrom->bWhat & (Byte) AM_ION) ||
2058            (pmmdFrom->bWhat & (Byte) AM_POLY) ||
2059 	   (pmmdTo->bWhat & (Byte) AM_HET) ||
2060            (pmmdTo->bWhat & (Byte) AM_POLY) ||
2061 	   (pmmdTo->bWhat & (Byte) AM_ION))) return;
2062 	paldFrom = GetLocation(GetAtomLocs(pmbdThis->pmadFrom, iModel), 0, ' ');
2063 	paldTo = GetLocation(GetAtomLocs(pmbdThis->pmadTo, iModel), 0, ' ');
2064 		/* these should call GetLocation and match AltConf/CoordSet */
2065 	 if (paldFrom && paldTo)
2066 	    {
2067               AddLineKin(pFile, paldFrom, paldTo);
2068            }
2069       }
2070   return;
2071 }
2072 
2073 
2074 
WriteKinBB(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)2075 void LIBCALLBACK WriteKinBB(PFB pfbThis, Int4 iModel,  Int4 iIndex, Pointer ptr)
2076 {
2077 
2078   PMBD pmbdThis = NULL;
2079   PALD paldFrom = NULL;
2080   PALD paldTo = NULL;
2081   FILE *pFile = NULL;
2082 
2083 
2084   if (!pfbThis) return;
2085   if (ptr) pFile = (FILE *) ptr;
2086   if (pfbThis->bMe == (Byte) AM_MBD)
2087       {
2088         pmbdThis = (PMBD) pfbThis;
2089 	if (!((pmbdThis->pmadFrom->bWhat & (Byte) AM_BACKBONE)
2090 	      && (pmbdThis->pmadTo->bWhat & (Byte) AM_BACKBONE))) return;
2091 	      /* both have to be backbone atoms */
2092 	if (pmbdThis->bWhat & (Byte) BOND_VIRTUAL) return;
2093 	     /* discard the virtual ones */
2094 	paldFrom = GetLocation(GetAtomLocs(pmbdThis->pmadFrom, iModel), 0, ' ');
2095 	paldTo = GetLocation(GetAtomLocs(pmbdThis->pmadTo, iModel), 0, ' ');
2096 	 if (paldFrom && paldTo)
2097 	    {
2098               AddLineKin(pFile, paldFrom, paldTo);
2099            }
2100       }
2101   return;
2102 }
2103 
2104 
WriteKinRes(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)2105 void LIBCALLBACK WriteKinRes(PFB pfbThis, Int4 iModel,  Int4 iIndex, Pointer ptr)
2106 {
2107 
2108   PMBD pmbdThis = NULL;
2109   PALD paldFrom = NULL;
2110   PALD paldTo = NULL;
2111   FILE *pFile = NULL;
2112 
2113 
2114   if (!pfbThis) return;
2115   if (ptr) pFile = (FILE *) ptr;
2116   if (pfbThis->bMe == (Byte) AM_MBD)
2117       {
2118         pmbdThis = (PMBD) pfbThis;
2119 	if (((pmbdThis->pmadFrom->bWhat & (Byte) AM_BACKBONE)
2120 	      && (pmbdThis->pmadTo->bWhat & (Byte) AM_BACKBONE))) return;
2121 	      /* no bonds connecting two backbone residues */
2122 	if (pmbdThis->bWhat & (Byte) BOND_VIRTUAL) return;
2123 	     /* discard the virtual ones */
2124 	paldFrom = GetLocation(GetAtomLocs(pmbdThis->pmadFrom, iModel), 0, ' ');
2125 	paldTo = GetLocation(GetAtomLocs(pmbdThis->pmadTo, iModel), 0, ' ');
2126 		/* these should call GetLocation and match AltConf/CoordSet */
2127 	 if (paldFrom && paldTo)
2128 	    {
2129               AddLineKin(pFile, paldFrom, paldTo);
2130            }
2131       }
2132   return;
2133 }
2134 
WriteKinAAResType(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)2135 void LIBCALLBACK WriteKinAAResType(PFB pfbThis, Int4 iModel,  Int4 iIndex, Pointer ptr)
2136 {
2137    PMGD pmgdThis = NULL;
2138    PVNMB pvnmbThis = NULL;
2139    FILE *pFile = NULL;
2140 
2141 
2142    if (!pfbThis) return;
2143    if (ptr) pFile = (FILE *) ptr;
2144 
2145    if (pfbThis->bMe == (Byte) AM_MGD)
2146      {
2147        pmgdThis = (PMGD) pfbThis;
2148        if (!(pmgdThis->bWhat & (Byte) RES_AA)) return;
2149        if (pmgdThis->pcIUPAC[0] == NCBIstdaaUC[iIndex])
2150          {
2151 	   pvnmbThis = pmgdThis->pvnmbBHead;
2152 	   while (pvnmbThis)
2153 	     {
2154 		 WriteKinRes((PFB) pvnmbThis->data.ptrvalue, iModel,  0,  pFile);
2155 		 pvnmbThis = pvnmbThis->next;
2156 	     }
2157 	 }
2158      }
2159 }
2160 
2161 
WriteKinNAResType(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)2162 void LIBCALLBACK WriteKinNAResType(PFB pfbThis, Int4 iModel,  Int4 iIndex, Pointer ptr)
2163 {
2164    PMGD pmgdThis = NULL;
2165    PVNMB pvnmbThis = NULL;
2166    FILE *pFile = NULL;
2167 
2168 
2169    if (!pfbThis) return;
2170    if (ptr) pFile = (FILE *) ptr;
2171    if (pfbThis->bMe == (Byte) AM_MGD)
2172      {
2173        pmgdThis = (PMGD) pfbThis;
2174        if (!((pmgdThis->bWhat & (Byte) RES_RNA) || (pmgdThis->bWhat & (Byte) RES_DNA))) return;
2175        if (pmgdThis->pcIUPAC[0] == NCBI4naUC[iIndex])
2176          {
2177            pvnmbThis = pmgdThis->pvnmbBHead;
2178 	   while (pvnmbThis)
2179 	     {
2180 		 WriteKinRes((PFB) pvnmbThis->data.ptrvalue, iModel,  0,  pFile);
2181 		 pvnmbThis = pvnmbThis->next;
2182 	     }
2183 	 }
2184      }
2185 }
2186 
2187 
WriteKinAlt(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)2188 void LIBCALLBACK WriteKinAlt(PFB pfbThis, Int4 iModel,  Int4 iIndex, Pointer ptr)
2189 {
2190   PMBD pmbdThis = NULL;
2191   PALD paldFrom = NULL;
2192   PALD paldTo = NULL;
2193   PMMD pmmdFrom = NULL;
2194   PMMD pmmdTo = NULL;
2195   FILE *pFile = NULL;
2196 
2197 
2198   if (!pfbThis) return;
2199   if (ptr) pFile = (FILE *) ptr;
2200   if (pfbThis->bMe == (Byte) AM_MBD)
2201       {
2202         pmbdThis = (PMBD) pfbThis;
2203 	if (pmbdThis->bWhat & (Byte) BOND_VIRTUAL) return;
2204 
2205 	paldFrom = GetLocation(GetAtomLocs(pmbdThis->pmadFrom, iModel), 0, (char) iIndex);
2206 	paldTo = GetLocation(GetAtomLocs(pmbdThis->pmadTo, iModel), 0, (char) iIndex);
2207 	if  ((paldFrom) && (paldTo == NULL))
2208 	   paldTo =  GetAtomLocs(pmbdThis->pmadTo, iModel);
2209 	else
2210 	if  ((paldTo) && (paldFrom == NULL))
2211 	   paldFrom =  GetAtomLocs(pmbdThis->pmadFrom, iModel);
2212 	if (paldFrom && paldTo)
2213 	    {
2214 	      pmmdFrom = GetParentMol((PFB) pmbdThis->pmadFrom);
2215 	      pmmdTo = GetParentMol((PFB) pmbdThis->pmadTo);
2216 	      if (pmmdFrom->bWhat & (Byte) AM_SOL) return; /* do no solvent */
2217 	      if (pmmdTo->bWhat & (Byte) AM_SOL) return; /* do no solvent */
2218 	      AddLineKin(pFile, paldFrom, paldTo);
2219             }
2220       }  /* is the node a bond */
2221   return;
2222 }
2223 
2224 
2225 
2226 
2227 
2228 
WriteKinIon(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)2229 void LIBCALLBACK WriteKinIon(PFB pfbThis, Int4 iModel,  Int4 iIndex, Pointer ptr)
2230 {
2231 
2232   PMAD pmadThis = NULL;
2233   PALD paldFrom = NULL;
2234   FILE *pFile = NULL;
2235   CharPtr pcElName = NULL;
2236 
2237 
2238   if (!pfbThis) return;
2239   if (ptr) pFile = (FILE *) ptr;
2240   if (pfbThis->bMe == (Byte) AM_MAD)
2241       {
2242         pmadThis = (PMAD) pfbThis;
2243 	if (!(pmadThis->bUpdate & (Byte) AM_ION)) return;
2244 	if (pmadThis->pvnmaLink->choice > MAX_ELEMENTS) return;
2245 	paldFrom = GetAtomLocs(pmadThis, iModel);
2246 	while (paldFrom)
2247 	  {
2248 	    pcElName = NULL;
2249 	    pcElName = ElementName((Int1)pmadThis->pvnmaLink->choice);
2250 	    if (!pcElName) pcElName = "?";
2251 	    fprintf(pFile, "@ballist {%s} color= %s radius= %3.1f nobutton master= {%s}\n",
2252 		    pcElName,
2253 		    KineColors[(int)ElementKinColors[(int)pmadThis->pvnmaLink->choice]],
2254 		    (float) (ElementSize((Int1)pmadThis->pvnmaLink->choice)),
2255 		    pcElName);
2256 	    fflush(pFile);
2257    	    fprintf(pFile, "{%s}  %8.3f, %8.3f, %8.3f \n",
2258 			pcElName,
2259 			paldFrom->pflvData[0],
2260 			paldFrom->pflvData[1],
2261 			paldFrom->pflvData[2]);
2262 	    fflush(pFile);
2263 	    paldFrom = paldFrom->next;
2264 	  }
2265       }
2266   return;
2267 }
2268 
2269 
WriteKinAtom(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)2270 void LIBCALLBACK WriteKinAtom(PFB pfbThis, Int4 iModel,  Int4 iIndex, Pointer ptr)
2271 {
2272    /* this does atomic coloring using lines from XYZ to midpoint of bond */
2273    /* deals with atomic type iIndex <0 or temperature iIndex >=0 */
2274   PMAD pmadThis = NULL;
2275   PMAD pmadTo = NULL;
2276   PMAD pmadFrom = NULL;
2277   PMBD pmbdThis = NULL;
2278   PALD paldFrom = NULL;
2279   PALD paldTo = NULL;
2280   PALD paldMid = NULL;
2281   PVNMB pvnmbThis = NULL;
2282   PMMD pmmdFrom = NULL;
2283   FILE *pFile = NULL;
2284   Int4 iTemp;
2285   FloatLo flAtemp;
2286   Int1 iElem;
2287   CharPtr pcElName = NULL;
2288 
2289 
2290   if (!pfbThis) return;
2291   if (ptr) pFile = (FILE *) ptr;
2292   if (pfbThis->bMe == (Byte) AM_MAD)
2293       {
2294         pmadThis = (PMAD) pfbThis;
2295 	pmmdFrom = GetParentMol((PFB)pmadThis);
2296 	if (pmmdFrom->bWhat & (Byte) AM_SOL) return; /* do no solvent */
2297 	paldFrom = GetLocation(GetAtomLocs(pmadThis, iModel),0,' ');
2298 	if (paldFrom)
2299 	  {
2300            if (iIndex >= 0) /* index of temp range 1 to (KIN_COLOR_THERM-1) */
2301              {
2302                if (paldFrom->iFloatNo == 4) /* istotropic */
2303                  {
2304 		    iTemp = (Int4) paldFrom->pflvData[4] * 100;
2305 		 }
2306 	       if (paldFrom->iFloatNo == 9) /* anisotropic */
2307 	         {  /* calculate the isotropic temp factor */
2308 		     flAtemp = (FloatLo) (((paldFrom->pflvData[4] +
2309 					    paldFrom->pflvData[5] +
2310 					    paldFrom->pflvData[6]) / 3));
2311 		     iTemp = (Int4) flAtemp * 100;
2312 		 }
2313 	       if (iTemp > TempsKine[iIndex]) return;  /* too high */
2314 	       if (iTemp < TempsKine[(iIndex-1)]) return; /* too low */
2315 	     }
2316 	   if (iIndex < 0) /* we are coloring by atom type */
2317 	     {  /* we cannily stuffed the element type in as a negative index */
2318 		 if (pmadThis->bUpdate & (Byte) AM_ION) return; /* done in a later pass */
2319 	         iElem = (Int1) -iIndex;
2320 		 if (pmadThis->pvnmaLink->choice != iElem) return;  /* too easy! */
2321 	     }
2322 
2323 	   pvnmbThis = pmadThis->pvnBonds;
2324 	    /* no bonds, not solvent atom needs a Temp sphere - color set in group */
2325 	   /*
2326 	   if ((pvnmbThis == NULL) && (iIndex >= 0))
2327 	     {
2328 		    pcElName = NULL;
2329 		    pcElName = ElementName((Int1)pmadThis->pvnmaLink->choice);
2330 		    if (!pcElName) pcElName = "?";
2331 		    fprintf(pFile, "@ballist {%s} radius= %3.1f nobutton master= {%s}\n",
2332 			pcElName,
2333 			(float) (ElementSize((Int1)pmadThis->pvnmaLink->choice)),
2334 			pcElName);
2335 		    fflush(pFile);
2336    		    fprintf(pFile, "{%s}  %8.3f, %8.3f, %8.3f \n",
2337 			pcElName,
2338 			paldFrom->pflvData[0],
2339 			paldFrom->pflvData[1],
2340 			paldFrom->pflvData[2]);
2341 		    fflush(pFile);
2342 		    return;
2343 	     } */
2344 	   while (pvnmbThis)
2345 	     {     /* walk the atom's bond list - all non-virtual ones */
2346 		 pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2347 		 if (!(pmbdThis->bWhat & (Byte) BOND_VIRTUAL))
2348 		   { /* make a half-way bond */
2349 		     pmadTo = pmbdThis->pmadTo;
2350 		     pmadFrom = pmadThis;
2351 		     if (pmadFrom == pmadTo) /* not the right one ? */
2352 		         pmadTo = pmbdThis->pmadFrom; /* use the other one */
2353 		     paldTo = GetAtomLocs(pmadTo,  iModel); /* just the first one */
2354 		     if (paldTo)
2355 		       {
2356 		         paldMid = NewALD(); /* allocate a phoney location */
2357 		         if (!paldMid) return;
2358 		         paldMid->pfbParent = (PFB) pmadFrom; /* link to the "from" atom */
2359 		         paldMid->iFloatNo = (Int1) 3;
2360 		         paldMid->cAltConf = ' ';
2361 		         paldMid->pflvData = FLVector(0,3);
2362 		         if (!paldMid->pflvData) return;
2363 			  /* midpoint between the two atoms */
2364 		         paldMid->pflvData[0] = (paldTo->pflvData[0] + paldFrom->pflvData[0]) / 2.0;
2365 		         paldMid->pflvData[1] = (paldTo->pflvData[1] + paldFrom->pflvData[1]) / 2.0;
2366 		         paldMid->pflvData[2] = (paldTo->pflvData[2] + paldFrom->pflvData[2]) / 2.0;
2367 		         if (paldMid && paldFrom)
2368 			   {
2369 			    AddLineKin(pFile, paldFrom, paldMid);
2370 			   }
2371 		         fflush(pFile);
2372 		         FreeALD(paldMid);
2373 		      }
2374 		    }
2375 		 pvnmbThis = pvnmbThis->next;
2376 	     }
2377 	  } /* if paldFrom */
2378       }  /* if AM_MAD */
2379   return;
2380 }
2381 
2382 
2383 
WriteKinAnimate(Int2 iModel,PDNMS pdnmsThis,FILE * pFile,Int2 iColor,Byte bKinRender,CharPtr pcComposition)2384 Int2 LIBCALL WriteKinAnimate(Int2 iModel,  PDNMS pdnmsThis,
2385 		FILE *pFile,  Int2 iColor, Byte bKinRender, CharPtr pcComposition)
2386 {
2387    Int2 iTest = 1;
2388    Int2 iHold = 0;
2389    PMSD pmsdThis = NULL;
2390    PDNMM pdnmmThis = NULL;
2391    PMMD pmmdThis = NULL;
2392    PMBD pmbdThis = NULL;
2393    PVNMB pvnmbThis = NULL;
2394    CharPtr pcColor = NULL;
2395    Boolean bFirst = TRUE;
2396    CharPtr pcKinMolName = NULL;
2397 
2398     /* this ignores ensembles - only animates models */
2399     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
2400     iHold = SetActiveModel(PFBFromDN(pdnmsThis),iModel);
2401 
2402 
2403  	  fprintf(pFile, "@group {model %d} animate dominant\n",iModel);
2404 	  fflush(pFile);
2405 	  if (bKinRender & (Byte) KIN_VIRTUAL)
2406 	    {
2407 		 fprintf(pFile, "@subgroup {virtual} master= {Virtual}\n");
2408 		 fflush(pFile);
2409 		 /* walk the molecules */
2410 		 pdnmmThis = pmsdThis->pdnmmHead;
2411 		 while (pdnmmThis)
2412 		   {
2413 		       ProgMon("Writing Kinemage");
2414 		       pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
2415 		       if ((pmmdThis->bWhat == AM_RNA) ||
2416 			    (pmmdThis->bWhat == AM_DNA) ||
2417 			    (pmmdThis->bWhat == AM_PROT))
2418 			  {
2419 			     pcKinMolName = GetKinMolName(pmmdThis);
2420 			     pcColor = KineColors[ColorNumKinBB[(pdnmmThis->choice % KIN_COLOR_NUM)]];
2421 			     fprintf(pFile, "@vectorlist {%s %s %d} color= %s\n",pcKinMolName,
2422 					 pmmdThis->pcMolName, (int)pdnmmThis->choice , pcColor);
2423 			     fflush(pFile);
2424 			     iTest = TraverseOneModel(pmmdThis->pdnmgHead,TRAVERSE_BOND,iModel,0,pFile,
2425                         WriteKinVirt);
2426 			     pvnmbThis = pmmdThis->pvnmbIRBHead;
2427 			     while (pvnmbThis) /* walk the IRBonds by hand */
2428 				{
2429 				    pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2430 				    WriteKinVirt((PFB) pmbdThis, iModel,  0,  pFile);
2431 				    pvnmbThis = pvnmbThis->next;
2432 				}
2433 
2434 			  }
2435 
2436 		       pdnmmThis = pdnmmThis->next;
2437 		   }
2438 
2439 	    }
2440 	  pdnmmThis = pmsdThis->pdnmmHead;
2441 	  if (bKinRender & (Byte) KIN_BACKBONE)
2442 	    {
2443 		fprintf(pFile, "@subgroup {backbone}");
2444 		if (bKinRender & (Byte) KIN_VIRTUAL) fprintf(pFile, " master= {Real} off\n");
2445 		else fprintf(pFile, "\n");
2446 		fflush(pFile);
2447 		/* walk the molecules */
2448 		 while (pdnmmThis)
2449 		   {
2450 		       pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
2451 		       if ((pmmdThis->bWhat == AM_RNA) ||
2452 			    (pmmdThis->bWhat == AM_DNA) ||
2453 			    (pmmdThis->bWhat == AM_PROT))
2454 			  {
2455 			     pcKinMolName = GetKinMolName(pmmdThis);
2456 			     pcColor = KineColors[ColorNumKinBB[(pdnmmThis->choice % KIN_COLOR_NUM)]];
2457 			     fprintf(pFile, "@vectorlist {%s %s %d} color= %s\n",pcKinMolName,
2458 					 pmmdThis->pcMolName, (int)pdnmmThis->choice , pcColor);
2459 			     fflush(pFile);
2460 			     iTest = TraverseOneModel(pmmdThis->pdnmgHead,TRAVERSE_BOND,iModel,0,pFile,
2461                         WriteKinBB);
2462 			     pvnmbThis = pmmdThis->pvnmbIRBHead;
2463 			     while (pvnmbThis) /* walk the IRBonds by hand */
2464 				{
2465 				    pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2466 				    WriteKinBB((PFB) pmbdThis, iModel,  0,  pFile);
2467 				    pvnmbThis = pvnmbThis->next;
2468 				}
2469 
2470 			  }
2471 
2472 		       pdnmmThis = pdnmmThis->next;
2473 		   }
2474 	    }
2475 	  pdnmmThis = pmsdThis->pdnmmHead;
2476 	  if (bKinRender & (Byte) KIN_RESIDUE)
2477 	    {
2478 		fprintf(pFile, "@subgroup {residues}");
2479 		if (bKinRender & (Byte) KIN_VIRTUAL) fprintf(pFile, " master= {Residues} off\n");
2480 		else fprintf(pFile, "\n");
2481 		fflush(pFile);
2482 		/* walk the molecules */
2483 		 while (pdnmmThis)
2484 		   {
2485 		       ProgMon("Writing Kinemage");
2486 		       pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
2487 		       if ((pmmdThis->bWhat == AM_RNA) ||
2488 			    (pmmdThis->bWhat == AM_DNA) ||
2489 			    (pmmdThis->bWhat == AM_PROT))
2490 			  {
2491 			     pcKinMolName = GetKinMolName(pmmdThis);
2492 			     pcColor = KineColors[ColorNumKinSC[(pdnmmThis->choice % KIN_COLOR_NUM)]];
2493 			     fprintf(pFile, "@vectorlist {%s %s %d} color= %s\n",pcKinMolName,
2494 					 pmmdThis->pcMolName, (int)pdnmmThis->choice , pcColor);
2495 			     fflush(pFile);
2496 			     iTest = TraverseOneModel(pmmdThis->pdnmgHead,TRAVERSE_BOND,iModel,0,pFile,
2497                         WriteKinRes);
2498 			     fprintf(pFile, "@vectorlist {x-links} nobutton color= yellow master= {X-links} \n");
2499 			     fflush(pFile);
2500 			     pvnmbThis = pmmdThis->pvnmbIRBHead;
2501 			     while (pvnmbThis) /* walk the IMBonds by hand */
2502 				{
2503 				    pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2504 				    WriteKinRes((PFB) pmbdThis, iModel,  0,  pFile);
2505 				    pvnmbThis = pvnmbThis->next;
2506 				}
2507 			  }
2508 
2509 		       pdnmmThis = pdnmmThis->next;
2510 		   }
2511 	    }
2512 	  pdnmmThis = pmsdThis->pdnmmHead;
2513 	  if (bKinRender & (Byte) KIN_HET)
2514 	    {
2515 	          bFirst = TRUE;
2516 		 /* walk the molecules */
2517 		  while (pdnmmThis)
2518 		   {
2519 		        pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
2520 			if (pmmdThis)
2521 		        if ((pmmdThis->bWhat == AM_HET) ||
2522                             (pmmdThis->bWhat == AM_POLY) ||
2523 			    (pmmdThis->bWhat == AM_ION))
2524 			  {
2525 			     if (bFirst)
2526 			       {
2527 				    fprintf(pFile, "@subgroup {hets} master= {Hets}\n");
2528 				    fflush(pFile);
2529 				    bFirst = FALSE;
2530 			       }
2531 			     pcColor = KineColors[ColorNumKinBB[(pdnmmThis->choice % KIN_COLOR_NUM)]];
2532 			     pcKinMolName = GetKinMolName(pmmdThis);
2533 			     fprintf(pFile, "@vectorlist {%s %d} color= %s\n",pcKinMolName,
2534 					(int)pdnmmThis->choice , pcColor);
2535 			     fflush(pFile);
2536 			     iTest = TraverseOneModel(pmmdThis->pdnmgHead,TRAVERSE_BOND,iModel,0,pFile,
2537                         WriteKinHet);
2538 			     pvnmbThis = pmmdThis->pvnmbIRBHead;
2539 			     while (pvnmbThis) /* walk the IRBonds by hand */
2540 				{
2541 				    pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2542 				    WriteKinHet((PFB) pmbdThis, iModel,  0,  pFile);
2543 				    pvnmbThis = pvnmbThis->next;
2544 				}
2545 			  }
2546 
2547 		       pdnmmThis = pdnmmThis->next;
2548 		   }
2549 	    }
2550 	 if ((bKinRender & (Byte) KIN_HET) && (pmsdThis->bWhat & (Byte) AM_ION))
2551            {
2552 	     fprintf(pFile,  "@subgroup {Ions} \n");
2553 	     fflush(pFile);
2554       	     iTest = TraverseOneModel(pmsdThis->pdnmmHead, TRAVERSE_ATOM,
2555 					iModel, iColor, (Pointer) pFile,
2556                     WriteKinIon);
2557 	     fflush(pFile);
2558 	   }
2559 	    /* do the rest of the inter-molecule bonds */
2560 	  pvnmbThis = pmsdThis->pvnmbIMBHead;
2561 	  if (((bKinRender & (Byte) KIN_HET)  ||
2562 	      (bKinRender & (Byte) KIN_RESIDUE)) && (pvnmbThis))
2563 	    {
2564 	         fprintf(pFile, "@subgroup {bonds}\n");
2565 		 fflush(pFile);
2566 		 if ((bKinRender & (Byte) KIN_HET)  ||  (bKinRender & (Byte) KIN_RESIDUE))
2567 		   {
2568 		     fprintf(pFile, "@subgroup {x-links} off\n");
2569 		     fprintf(pFile, "@vectorlist {x-links} color= yellow master= {X-links}");
2570 		     fflush(pFile);
2571 		     while (pvnmbThis) /* walk the IMBonds by hand */
2572 		     {
2573 		      pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2574 		      if (bKinRender & (Byte) KIN_HET) WriteKinHet((PFB) pmbdThis, iModel,  0,  pFile);
2575 		      if (bKinRender & (Byte) KIN_RESIDUE) WriteKinRes((PFB) pmbdThis, iModel,  0,  pFile);
2576 	 	      pvnmbThis = pvnmbThis->next;
2577 		     }
2578 		   }
2579 	    }
2580 
2581     iHold = SetActiveModel(PFBFromDN(pdnmsThis),iHold);
2582     return iTest;
2583 }
2584 
KinColorFromSS(PMGD pmgdThis)2585 Int2 LIBCALL KinColorFromSS(PMGD pmgdThis)
2586 {
2587 	Int2 rsult = 0;
2588 
2589       switch ((int) (pmgdThis->bNCBISecStru))
2590        {
2591 	  case SS_HELIX:
2592 	     return 8;
2593 	  case SS_SHEET:
2594 	  case SS_STRAND:
2595 	     return 10;
2596 	  case SS_TURN:
2597 	     return 11;
2598 	  default:
2599 	     rsult = 6;
2600 	}
2601    return rsult;
2602 }
2603 
NameFromSS(PMGD pmgdThis)2604 CharPtr LIBCALL NameFromSS(PMGD pmgdThis)
2605 {
2606 	CharPtr rsult = NULL;
2607 
2608       switch ((int) (pmgdThis->bNCBISecStru))
2609        {
2610 	  case SS_HELIX:
2611 	     return "Helix";
2612 	  case SS_SHEET:
2613 	  case SS_STRAND:
2614 	     return "Sheet";
2615 	  case SS_TURN:
2616 	     return "Turn";
2617 	  default:
2618 	     rsult = "Prot";
2619 	}
2620    return rsult;
2621 }
2622 
WriteKinModelByType(Int2 iModel,PDNMS pdnmsThis,FILE * pFile,Int2 iColor,Byte bKinRender,CharPtr pcComposition)2623 Int2 LIBCALL WriteKinModelByType(Int2 iModel,  PDNMS pdnmsThis,
2624 		FILE *pFile,  Int2 iColor, Byte bKinRender, CharPtr pcComposition)
2625 
2626 {  /* this does coloring by secondary structure and by residue type */
2627 
2628     PMSD pmsdThis = NULL;
2629     PDNMM pdnmmThis = NULL;
2630     PDNMG pdnmgThis = NULL;
2631     PMMD pmmdThis = NULL;
2632     PMGD pmgdFrom = NULL;
2633     PMBD pmbdThis = NULL;
2634     PVNMA pvnmaThis = NULL;
2635     PVNMB pvnmbThis = NULL;
2636     PMAD pmadFrom = NULL;
2637     PMAD pmadThis = NULL;
2638     PMAD pmadTo = NULL;
2639     PALD paldMid = NULL;
2640     PALD paldTo = NULL;
2641     PALD paldFrom = NULL;
2642     Int2 iHold = 0;
2643     Int4 iIndex;
2644     Int2 iTest = 0;
2645     Boolean bFirst = TRUE;
2646     Byte bOldSS = 0x00;
2647     CharPtr pcColor = NULL;
2648     CharPtr pcKinMolName = NULL;
2649 
2650     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
2651     iHold = SetActiveModel(PFBFromDN(pdnmsThis),iModel);
2652 
2653     pdnmmThis = pmsdThis->pdnmmHead; /* the top of the molecule list */
2654 
2655       /* individual models... */
2656 
2657     while (pdnmmThis)  /* walk the molecules individually - each has a group */
2658       {
2659 	   ProgMon("Writing Kinemage");
2660 	   bFirst = TRUE;
2661 	   pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
2662 
2663 	   if ((pmmdThis->bWhat == AM_RNA) ||
2664 		(pmmdThis->bWhat == AM_DNA) ||
2665 		(pmmdThis->bWhat == AM_PROT))
2666 	    {
2667 	        pcKinMolName = GetKinMolName(pmmdThis);
2668 		fprintf(pFile, "@group {%d %s %s}\n",(int)pdnmmThis->choice,
2669 		  pcKinMolName,  pmmdThis->pcMolName);
2670 		fflush(pFile);
2671 	   	if (bKinRender & (Byte) KIN_VIRTUAL)
2672 		  {
2673 		    bOldSS = (Byte) 0x00;
2674 		    fprintf(pFile, "@subgroup {BB Virtual} dominant\n");
2675  		    pdnmgThis = pmmdThis->pdnmgHead;
2676 		    while (pdnmgThis)
2677 		      {   /* walk the graphs */
2678 			   pmgdFrom = (PMGD) pdnmgThis->data.ptrvalue;
2679 			   if ((bOldSS != (Byte) (pmgdFrom->bNCBISecStru)) || bFirst)
2680 			      {  /* change in sec stru detected */
2681 			        bFirst = FALSE;
2682 			        if (pmmdThis->bWhat == AM_RNA)
2683 				     fprintf(pFile, "@vectorlist {rna} color= %s master= {NA}\n",
2684 				         KineColors[KinColorFromSS(pmgdFrom)]);
2685 				if (pmmdThis->bWhat == AM_DNA)
2686 				      fprintf(pFile, "@vectorlist {dna} color= %s master= {NA}\n",
2687 					 KineColors[KinColorFromSS(pmgdFrom)]);
2688 				if (pmmdThis->bWhat == AM_PROT)
2689 				    fprintf(pFile, "@vectorlist {%s} color= %s master= {%s}\n",
2690 					NameFromSS(pmgdFrom),  KineColors[KinColorFromSS(pmgdFrom)],
2691 					NameFromSS(pmgdFrom));
2692 			        fflush(pFile);
2693 			      }
2694 			   bOldSS = (Byte) (pmgdFrom->bNCBISecStru);
2695 		           pvnmaThis = pmgdFrom->pvnmaAHead;
2696 			   while (pvnmaThis)
2697 			     {  /* find the Virtual bonds for each graph */
2698 			         pmadThis = (PMAD) pvnmaThis->data.ptrvalue;
2699 				 pvnmbThis = pmadThis->pvnBonds;
2700 				 while (((pmadThis->bWhat & (Byte) AM_CALPHA) || (pmadThis->bWhat & (Byte) AM_PALPHA))
2701 					    && (pvnmbThis))
2702 				   {
2703 				    pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2704 				    if (pmbdThis->bWhat & (Byte) BOND_VIRTUAL)
2705 				    {
2706 					pmadFrom = pmbdThis->pmadFrom;
2707 					if (pmgdFrom != GetParentGraph((PFB) pmadFrom))
2708 					    {
2709 						pmadFrom = pmbdThis->pmadTo;
2710 						pmadTo = pmbdThis->pmadFrom;
2711 					    }
2712 					else
2713 					    pmadTo = pmbdThis->pmadTo;
2714 					if ((pmadTo) && (pmadFrom))
2715 					{
2716 					    paldTo = NULL;
2717 					    paldMid = NULL;
2718 					    paldFrom = NULL;
2719 					    paldTo = GetLocation(GetAtomLocs(pmadTo,  iModel),0,' ');
2720 					    paldFrom = GetLocation(GetAtomLocs(pmadFrom, iModel), 0,' ');
2721 					    paldMid = NewALD(); /* allocate a phoney location */
2722 					    if (!paldMid) return -1;
2723 					    if (paldTo && paldFrom)
2724 					     {
2725 						paldMid->pfbParent =(PFB) pmadFrom; /* link to the "from" atom */
2726 						paldMid->iFloatNo = (Int1) 3;
2727 						paldMid->cAltConf = ' ';
2728 						paldMid->pflvData = FLVector(0, 3);
2729 						if (!paldMid->pflvData) return -2;
2730 						/* midpoint between the two atoms */
2731 						paldMid->pflvData[0] = (paldTo->pflvData[0] + paldFrom->pflvData[0]) / 2.0;
2732 						paldMid->pflvData[1] = (paldTo->pflvData[1] + paldFrom->pflvData[1]) / 2.0;
2733 						paldMid->pflvData[2] = (paldTo->pflvData[2] + paldFrom->pflvData[2]) / 2.0;
2734 						AddLineKin(pFile, paldFrom, paldMid);
2735 						fflush(pFile);
2736 					      }
2737 
2738 					    FreeALD(paldMid);
2739 					  }
2740 
2741 					}  /* if virtual bond */
2742 				      pvnmbThis = pvnmbThis->next;
2743 				    }  /* while alpha carbon or P and bonds */
2744 				 pvnmaThis = pvnmaThis->next;
2745 			     } /* while atom */
2746 			   pmadFrom = NULL;
2747 			   pdnmgThis = pdnmgThis->next;
2748 		      }  /* while graphs */
2749 		  }  /* if virtual render */
2750 		bFirst = TRUE;
2751 		if (bKinRender & (Byte) KIN_BACKBONE)
2752 		  {
2753 		    bOldSS = (Byte) 0x00;
2754 		    fprintf(pFile, "@subgroup {BB Real} dominant ");
2755 		    if (bKinRender & (Byte) KIN_VIRTUAL) fprintf(pFile,  "off\n");
2756 		    else fprintf(pFile, "\n");
2757 		    fflush(pFile);
2758  		    pdnmgThis = pmmdThis->pdnmgHead;
2759 		    while (pdnmgThis)
2760 		      {   /* walk the graphs */
2761 			   pmgdFrom = (PMGD) pdnmgThis->data.ptrvalue;
2762 			   if ((bOldSS != (Byte) (pmgdFrom->bNCBISecStru)) || bFirst)
2763 			      {  /* change in sec stru detected */
2764 			        bFirst = FALSE;
2765 			        if (pmmdThis->bWhat == AM_RNA)
2766 				     fprintf(pFile, "@vectorlist {rna} color= %s master= {NA}\n",
2767 				         KineColors[KinColorFromSS(pmgdFrom)]);
2768 				if (pmmdThis->bWhat == AM_DNA)
2769 				      fprintf(pFile, "@vectorlist {dna} color= %s master= {NA}\n",
2770 					 KineColors[KinColorFromSS(pmgdFrom)]);
2771 				if (pmmdThis->bWhat == AM_PROT)
2772 				    fprintf(pFile, "@vectorlist {%s} color= %s master= {%s}\n",
2773 					NameFromSS(pmgdFrom),  KineColors[KinColorFromSS(pmgdFrom)],
2774 					NameFromSS(pmgdFrom));
2775 			        fflush(pFile);
2776 			      }
2777 			   bOldSS = (Byte) (pmgdFrom->bNCBISecStru);
2778 			   pvnmbThis = pmgdFrom->pvnmbBHead;
2779 			   while(pvnmbThis)  /* walk the bond list */
2780 			     {
2781 				pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2782 				WriteKinBB((PFB) pmbdThis, iModel,  0,  pFile);
2783 				pvnmbThis = pvnmbThis->next;
2784 			     }
2785 			   pdnmgThis = pdnmgThis->next;
2786 		      }  /* while graphs */
2787 		      /* do the rest of the backbone - coloring sucks, but... */
2788 		     pvnmbThis = pmmdThis->pvnmbIRBHead;
2789 		     if (pmmdThis->bWhat == AM_RNA)
2790 			  fprintf(pFile, "@vectorlist {bb} color= default master= {NA}\n");
2791 		     if (pmmdThis->bWhat == AM_DNA)
2792 			  fprintf(pFile, "@vectorlist {bb} color= default master= {NA}\n");
2793 		     if (pmmdThis->bWhat == AM_PROT)
2794 			  fprintf(pFile, "@vectorlist {bb} color= default master= {Prot}\n");
2795 		     while (pvnmbThis) /* walk the IMBonds by hand */
2796 			{
2797 			    pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2798 			    WriteKinBB((PFB) pmbdThis, iModel,  0,  pFile);
2799 			    pvnmbThis = pvnmbThis->next;
2800 			}
2801 		  } /* if Backbone */
2802 	    } /* if DNA or protein or RNA */
2803 	  pdnmmThis = pdnmmThis->next;
2804       } /* while molecule */
2805 
2806     if (bKinRender & (Byte) KIN_RESIDUE)
2807       {
2808 	 /* traverse all the graphs - strip out all the residues one at a time */
2809 	fprintf(pFile, "@group {Residues} off\n");
2810 	fflush(pFile);
2811  	for (iIndex = 0;  iIndex < MAX_NCBIstdaa;  iIndex++)
2812 	{
2813 	    if (StringChr(pcComposition, NCBIstdaaUC[iIndex]))
2814 	      {  /* indicates the amino acid is indeed in the structrure */
2815 		ProgMon("Writing Kinemage");
2816 		fprintf(pFile, "@subgroup {%s} dominant \n",  AminoAcidNameFromIdx(iIndex,  USE_MIXCASE));
2817 		fprintf(pFile,  "@vectorlist {aa}  color= %s master= {Prot}\n", KineColors[KinAAColor[iIndex]] );
2818     		iTest = TraverseOneModel(pmsdThis->pdnmmHead, TRAVERSE_GRAPH,
2819 					iModel, (Int4) iIndex, (Pointer) pFile,
2820                     WriteKinAAResType);
2821 	      }
2822 	}
2823        for (iIndex = 0;  iIndex < MAX_NCBI4na; iIndex++)
2824 	{
2825 	    if (StringChr(pcComposition, NCBI4naLC[iIndex]))
2826 	      {  /* indicates the residue is indeed in the structrure */
2827 		ProgMon("Writing Kinemage");
2828 		fprintf(pFile, "@subgroup {%c} dominant \n",  NCBI4naLC[iIndex]);
2829 		fprintf(pFile,  "@vectorlist {na} color= %s master = {NA}\n", KineColors[KinNAColor[iIndex]]);
2830     		iTest = TraverseOneModel(pmsdThis->pdnmmHead, TRAVERSE_GRAPH,
2831 					iModel, (Int4) iIndex, (Pointer) pFile,
2832                     WriteKinNAResType);
2833 	      }
2834 	}
2835       }
2836 
2837     pdnmmThis = pmsdThis->pdnmmHead; /* the top of the molecule list */
2838     while (pdnmmThis)  /* walk the molecules for hets or ions */
2839       {
2840 	  pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
2841 
2842 	  if ((pmmdThis->bWhat == (Byte) AM_HET) ||
2843               (pmmdThis->bWhat == (Byte) AM_POLY) ||
2844               (pmmdThis->bWhat == (Byte) AM_ION))
2845 	    {
2846 	        fprintf(pFile, "@group {%d het} dominant\n",(int)pdnmmThis->choice);
2847 		fflush(pFile);
2848 		pcColor = KineColors[ColorNumKinBB[(pdnmmThis->choice % KIN_COLOR_NUM)]];
2849 		fprintf(pFile, "@vectorlist {het} color= %s master= {Hets}\n",  pcColor);
2850 		fflush(pFile);
2851 		iTest = TraverseOneModel(pmmdThis->pdnmgHead, TRAVERSE_BOND,
2852 					iModel, iColor, (Pointer) pFile,
2853                     WriteKinHet);
2854 		if (pmmdThis->bWhat == AM_ION)
2855 		  {
2856 		     iTest = TraverseOneModel(pmmdThis->pdnmgHead, TRAVERSE_ATOM,
2857 					iModel, iColor, (Pointer) pFile,
2858                     WriteKinIon);
2859 		  }
2860 		 pvnmbThis = pmmdThis->pvnmbIRBHead;
2861 		 while (pvnmbThis) /* walk the IRBonds by hand */
2862 		   {
2863 		    pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2864 		    WriteKinHet((PFB) pmbdThis, iModel,  0,  pFile);
2865 		    pvnmbThis = pvnmbThis->next;
2866 		   }
2867 
2868 		fflush(pFile);
2869 	    }
2870 	  pdnmmThis = pdnmmThis->next;
2871       }  /* while pdnmmThis - traverses the molecules */
2872 
2873     /* traverse the inter-molecule bonds */
2874     pvnmbThis = pmsdThis->pvnmbIMBHead;
2875     if (((bKinRender & (Byte) KIN_HET) ||
2876 	      (bKinRender & (Byte) KIN_RESIDUE)) && (pvnmbThis))
2877       {
2878 
2879 		 fprintf(pFile, "@group {X-links} dominant master= {X-links}\n");
2880 		 fflush(pFile);
2881 		 if ((bKinRender & (Byte) KIN_HET)  ||  (bKinRender & (Byte) KIN_RESIDUE))
2882 		   {
2883 		     fprintf(pFile, "@vectorlist {real} color= yellow ");
2884 		     if (bKinRender & (Byte) KIN_VIRTUAL) fprintf(pFile, "master= {X-links} off\n");
2885 		     else fprintf(pFile, "\n");
2886 		     fflush(pFile);
2887 		   }
2888 	        while (pvnmbThis) /* walk the IMBonds by hand */
2889 		  {
2890 		     pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
2891 		     if (bKinRender & (Byte) KIN_HET) WriteKinHet((PFB) pmbdThis, iModel,  0,  pFile);
2892 		     if (bKinRender & (Byte) KIN_RESIDUE) WriteKinRes((PFB) pmbdThis, iModel,  0,  pFile);
2893 	 	     pvnmbThis = pvnmbThis->next;
2894 		  }
2895       }
2896 
2897     iHold = SetActiveModel(PFBFromDN(pdnmsThis),iHold);
2898     return iTest;
2899 }
2900 
2901 
WriteKinModel(Int2 iModel,PDNMS pdnmsThis,FILE * pFile,Int2 iColor,Byte bKinRender,CharPtr pcComposition)2902 Int2 LIBCALL WriteKinModel(Int2 iModel,  PDNMS pdnmsThis,
2903 		FILE *pFile,  Int2 iColor, Byte bKinRender, CharPtr pcComposition)
2904 {
2905    Int2 iTest = 1;
2906    Int2 iHold = 0;
2907    Int2 iTemp = 0;
2908    PMSD pmsdThis = NULL;
2909    PDNMM pdnmmThis = NULL;
2910    PVNMB pvnmbThis = NULL;
2911    PMMD pmmdThis = NULL;
2912    PMBD pmbdThis = NULL;
2913    PMLD pmldThis = NULL;
2914    PDNML pdnmlThis = NULL;
2915    CharPtr pcColor = NULL;
2916    CharPtr pcThis = NULL;
2917    CharPtr pcElName = NULL;
2918 
2919 
2920     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
2921     iHold = SetActiveModel(PFBFromDN(pdnmsThis),iModel);
2922     if (bKinRender == KIN_DEFAULT)
2923       {
2924         bKinRender = (Byte) (KIN_VIRTUAL | KIN_HET); /* lowest settings */
2925 	iColor = KIN_COLOR_NUMBER;
2926       }
2927     if (iColor == KIN_COLOR_DEFAULT) iColor = KIN_COLOR_NUMBER;
2928 
2929 
2930     if (iColor == KIN_COLOR_TEMP)
2931       {  /* all the bonds are binned into buttons according to temp */
2932          /* non-solvent lone atoms are spheres */
2933         for (iTemp = 1; iTemp < KIN_COLOR_THERM ; iTemp++)
2934            {
2935                   pcColor = KineColors[ThermKine[iTemp]];
2936 		  fprintf(pFile,  "@group {T %d} dominant\n",(int) (TempsKine[iTemp]/100) );
2937 		  fflush(pFile);
2938 		  fprintf(pFile,  "@vectorlist {atom} color= %s\n", pcColor);
2939 		  fflush(pFile);
2940 		  ProgMon("Writing Kinemage");
2941 		  iTest = TraverseOneModel(pmsdThis->pdnmmHead, TRAVERSE_ATOM,
2942 					iModel, (Int4) iTemp, (Pointer) pFile,
2943                     WriteKinAtom);
2944 		  fflush(pFile);
2945            }
2946          goto donetype;
2947       }
2948     if (iColor == KIN_COLOR_ATOM)
2949       {  /* all the atoms are binned into atom groups */
2950          for (iTemp = 0;  iTemp < MAX_KIN_ATOMS;  iTemp++)
2951 	    {
2952 	        pcElName =  ElementName(KinAtoms[iTemp]);
2953 		if (!pcElName) pcElName = "?";
2954 		pcColor = KineColors[ElementKinColors[KinAtoms[iTemp]]];
2955 		fprintf(pFile, "@group {%s} dominant\n",pcElName);
2956 		fflush(pFile);
2957 		fprintf(pFile,  "@vectorlist {atom} color= %s\n", pcColor);
2958 		fflush(pFile);
2959 	 	ProgMon("Writing Kinemage");
2960 		iTest = TraverseOneModel(pmsdThis->pdnmmHead, TRAVERSE_ATOM,
2961 					iModel, (Int4) -KinAtoms[iTemp], (Pointer) pFile,
2962                     WriteKinAtom);
2963 		fflush(pFile);
2964 	    }
2965 	  /* then do all the ions */
2966 	if (pmsdThis->bWhat & (Byte) AM_ION)
2967           {
2968  	    fprintf(pFile,  "@group {Ions} \n");
2969 	    fflush(pFile);
2970       	    iTest = TraverseOneModel(pmsdThis->pdnmmHead, TRAVERSE_ATOM,
2971 					iModel, iColor, (Pointer) pFile,
2972                     WriteKinIon);
2973 	    fflush(pFile);
2974 	  }
2975 	goto donetype;
2976       }
2977 
2978     if (iColor == KIN_COLOR_TYPE)
2979       {
2980         iTest = WriteKinModelByType(iModel,  pdnmsThis,  pFile, iColor, bKinRender,  pcComposition);
2981 	goto donetype;
2982       }
2983 
2984     pdnmmThis = pmsdThis->pdnmmHead; /* the top of the molecule list */
2985 
2986       /* individual models... */
2987 
2988     while (pdnmmThis)  /* walk the molecules individually - each has a group */
2989       {
2990 	  pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
2991 
2992 	   if ((pmmdThis->bWhat == AM_RNA) ||
2993 		(pmmdThis->bWhat == AM_DNA) ||
2994 		(pmmdThis->bWhat == AM_PROT))
2995 	    {
2996 		ProgMon("Writing Kinemage");
2997 		fprintf(pFile, "@group {%d %s %s}\n",(int)pdnmmThis->choice,
2998 		  GetKinMolName(pmmdThis),  pmmdThis->pcMolName);
2999 		fflush(pFile);
3000 		if ((bKinRender & (Byte) KIN_VIRTUAL) || (bKinRender & (Byte) KIN_BACKBONE))
3001 		  { /* make a backbone subgroup */
3002 		    fprintf(pFile, "@subgroup {backbone} dominant\n");
3003 		    fflush(pFile);
3004 		  }
3005 	   	if (bKinRender & (Byte) KIN_VIRTUAL)
3006 		  {
3007 		    if (iColor == KIN_COLOR_NUMBER)
3008 			{
3009 			     pcColor = KineColors[ColorNumKinBB[(pdnmmThis->choice % KIN_COLOR_NUM)]];
3010 			     fprintf(pFile, "@vectorlist {virtual} color= %s master= {Virtual}\n", pcColor);
3011 			     fflush(pFile);
3012 			     iTest = TraverseOneModel(pmmdThis->pdnmgHead, TRAVERSE_BOND,
3013 					iModel, iColor, (Pointer) pFile,
3014                     WriteKinVirt);
3015 			}
3016 
3017 			fflush(pFile);
3018 		  }
3019 		if (bKinRender & (Byte) KIN_BACKBONE)
3020 		  {
3021 		      if (iColor == KIN_COLOR_NUMBER)
3022 			  {
3023 			      pcColor =  KineColors[ColorNumKinBB[(pdnmmThis->choice % KIN_COLOR_NUM)]];
3024 			      fprintf(pFile, "@vectorlist {real} color= %s", pcColor );
3025 			      if (bKinRender & (Byte) KIN_VIRTUAL) fprintf(pFile, " master= {Real} off\n");
3026 			      else fprintf(pFile, "\n");
3027 			      fflush(pFile);
3028 			      iTest = TraverseOneModel(pmmdThis->pdnmgHead, TRAVERSE_BOND,
3029 					iModel, iColor, (Pointer) pFile,
3030                     WriteKinBB);
3031 			      pvnmbThis = pmmdThis->pvnmbIRBHead;
3032 			      while (pvnmbThis) /* walk the IMBonds by hand */
3033 				{
3034 				    pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
3035 				    WriteKinBB((PFB) pmbdThis, iModel,  0,  pFile);
3036 				    pvnmbThis = pvnmbThis->next;
3037 				}
3038 			  }
3039 		 	else {/*do the KIN_COLOR_TYPE with SecStru */ ;}
3040 			fflush(pFile);
3041 		  }
3042 		   /* color-by number is one-pass residues */
3043 		if  ((iColor == KIN_COLOR_NUMBER) &&
3044 	         (bKinRender & (Byte) KIN_RESIDUE))
3045 		  {
3046 		    pcColor =  KineColors[ColorNumKinSC[(pdnmmThis->choice % KIN_COLOR_NUM)]];
3047 		    fprintf(pFile, "@subgroup {residues} dominant master= {Residues} off\n");
3048 		    fflush(pFile);
3049 		    if (pmmdThis->bWhat == AM_RNA)
3050 		       fprintf(pFile, "@vectorlist {nucleic acids} color= %s\n", pcColor);
3051 		    if (pmmdThis->bWhat == AM_DNA)
3052 		       fprintf(pFile, "@vectorlist {nucleic acids} color= %s\n", pcColor);
3053 		    if (pmmdThis->bWhat == AM_PROT)
3054 		        fprintf(pFile, "@vectorlist {amino acids} color= %s\n", pcColor);
3055 		    fflush(pFile);
3056 		    iTest = TraverseOneModel(pmmdThis->pdnmgHead, TRAVERSE_BOND,
3057 					iModel, iColor, (Pointer) pFile,
3058                     WriteKinRes);
3059 		    fflush(pFile);
3060 
3061 		     /* make all the molecule's residue in one pass */
3062 		  }  /* if making residues */
3063 	       if (bKinRender & (Byte) KIN_RESIDUE)
3064 	            {  /* do inter-res bonds by hand */
3065 			fprintf(pFile, "@subgroup {x-links} dominant\n");
3066 			fflush(pFile);
3067 			if (bKinRender & (Byte) KIN_RESIDUE)
3068 			   {
3069 			     fprintf(pFile, "@vectorlist {real}  color= yellow master= {Real} off\n");
3070 			     fflush(pFile);
3071 			    }
3072 			pvnmbThis = pmmdThis->pvnmbIRBHead;
3073 			while (pvnmbThis) /* walk the IMBonds by hand */
3074 			    {
3075 				pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
3076 	 			if (bKinRender & (Byte) KIN_RESIDUE) WriteKinRes((PFB) pmbdThis, iModel,  0,  pFile);
3077 	 		 	pvnmbThis = pvnmbThis->next;
3078 			    }
3079 		    }
3080 
3081 	     } /* if making DNA, RNA or PROT */
3082 
3083 	  if ((pmmdThis->bWhat == (Byte) AM_HET) ||
3084                (pmmdThis->bWhat == (Byte) AM_POLY) ||
3085                (pmmdThis->bWhat == (Byte) AM_ION))
3086 	    {
3087 	        fprintf(pFile, "@group {%d het} dominant\n",(int)pdnmmThis->choice);
3088 		fflush(pFile);
3089 		pcColor = KineColors[ColorNumKinBB[(pdnmmThis->choice % KIN_COLOR_NUM)]];
3090 		fprintf(pFile, "@vectorlist {het} color= %s master= {Hets}\n",  pcColor);
3091 		fflush(pFile);
3092 		iTest = TraverseOneModel(pmmdThis->pdnmgHead, TRAVERSE_BOND,
3093 					iModel, iColor, (Pointer) pFile,
3094                     WriteKinHet);
3095 		if (pmmdThis->bWhat == AM_ION)
3096 		  {
3097 		     iTest = TraverseOneModel(pmmdThis->pdnmgHead, TRAVERSE_ATOM,
3098 					iModel, iColor, (Pointer) pFile,
3099                     WriteKinIon);
3100 		  }
3101 		pvnmbThis = pmmdThis->pvnmbIRBHead;
3102 	        while (pvnmbThis) /* walk the IRBonds by hand */
3103 		  {
3104 		    pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
3105 		    WriteKinHet((PFB) pmbdThis, iModel,  0,  pFile);
3106 		    pvnmbThis = pvnmbThis->next;
3107 		  }
3108 		fflush(pFile);
3109 	    }
3110 	  pdnmmThis = pdnmmThis->next;
3111       }  /* while pdnmmThis - traverses the molecules */
3112 
3113       /* do the rest of the inter-molecule bonds */
3114     pvnmbThis = pmsdThis->pvnmbIMBHead;
3115     if (((bKinRender & (Byte) KIN_HET) ||
3116 	      (bKinRender & (Byte) KIN_RESIDUE)) && (pvnmbThis))
3117       {
3118 
3119 		 fprintf(pFile, "@group {X-links} dominant \n");
3120 		 fflush(pFile);
3121 		 if ((bKinRender & (Byte) KIN_HET)  ||  (bKinRender & (Byte) KIN_RESIDUE))
3122 		   {
3123 		     fprintf(pFile, "@vectorlist {real}  color= yellow ");
3124 		     if (bKinRender & (Byte) KIN_VIRTUAL) fprintf(pFile, "master= {Real} off\n");
3125 		     else fprintf(pFile, "\n");
3126 		     fflush(pFile);
3127 		   }
3128 	        while (pvnmbThis) /* walk the IMBonds by hand */
3129 		  {
3130 		     pmbdThis = (PMBD) pvnmbThis->data.ptrvalue;
3131 		     if (bKinRender & (Byte) KIN_HET) WriteKinHet((PFB) pmbdThis, iModel,  0,  pFile);
3132 		     if (bKinRender & (Byte) KIN_RESIDUE) WriteKinRes((PFB) pmbdThis, iModel,  0,  pFile);
3133 	 	     pvnmbThis = pvnmbThis->next;
3134 		  }
3135       }
3136    donetype:
3137      if (bKinRender & (Byte) KIN_ALTCONF)
3138        {
3139 	pdnmlThis = DValNodeFindNext(pmsdThis->pdnmlModels, NULL, iModel); /* find the model */
3140  	if (pdnmlThis)
3141    	  {
3142 	     /* this connects all alternative conformers recorded regardless of what they are */
3143 	     /* they are colored by ocurrence, never by type */
3144 	     pmldThis = (PMLD) pdnmlThis->data.ptrvalue;
3145 	     pcThis = pmldThis->pcAltConf;
3146 	     if (pcThis) /* model has to have alt-confs */
3147 	     while (StringLen(pcThis))
3148 	        {
3149 		     if (pcThis[0] != ' ')  /* is it really an alt-conf */
3150 		       {
3151 		           fprintf(pFile, "@group {Alt %c} animate dominant\n",(char) pcThis[0]);
3152 			   fprintf(pFile, "@vectorlist {%c} color= %s\n", (char) pcThis[0],
3153 			           KineColors[ColorNumKinAC[StringLen(pcThis) % KIN_COLOR_NUM]]);
3154 			   iTest = TraverseOneModel(pdnmsThis, TRAVERSE_BOND,
3155 						    iModel,(Int4) pcThis[0], (Pointer) pFile,
3156                             WriteKinAlt);
3157 			   fflush(pFile);
3158 		       }
3159 		     pcThis = (CharPtr) &pcThis[1]; /* move the string up */
3160 		}
3161 	  } /* does the model have a location? */
3162        } /* if alt confs */
3163 
3164     iHold = SetActiveModel(PFBFromDN(pdnmsThis),iHold);
3165     return iTest;
3166 }
3167 
3168 
3169 
WriteKinModelList(PDNMS pdnmsThis,FILE * pFile,Int2 iColor,Byte bKinRender,Int2 iNumModels,Int2Ptr i2Vec)3170 Int2 LIBCALL WriteKinModelList(PDNMS pdnmsThis,  FILE *pFile,  Int2 iColor, Byte bKinRender,
3171 				 Int2 iNumModels,  Int2Ptr i2Vec )
3172 {
3173     Int2 iIndex;
3174     Int2 iTest = 0;
3175     CharPtr pcComposition = NULL;
3176     PMSD pmsdThis = NULL;
3177     PDNML pdnmlThis = NULL;
3178     PMLD  pmldThis = NULL;
3179     Int2 iPDBCount = 0;
3180 
3181 /*	if (bKinRender == KIN_DEFAULT) bKinRender = KIN_VIRTUAL;  DONE ELSEWHERE */
3182 
3183     fprintf(pFile, "@text\n");
3184     fprintf(pFile, "NCBI - Generated Kinemage File From MMDB\n\n");
3185     fflush(pFile);
3186 
3187     if (!pdnmsThis) return iTest;
3188     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
3189     if (!(pmsdThis->bMe == (Byte) AM_MSD)) return iTest;
3190 
3191     WriteKinHeader(pdnmsThis, pFile);  /* puts @text with compound, source */
3192     pcComposition = WriteKinSeq(pdnmsThis, pFile); /* puts sequence, returns composition string */
3193 
3194     for (iIndex = 0; iIndex < iNumModels; iIndex++)
3195        {
3196         pdnmlThis = NULL;
3197 	pdnmlThis = DValNodeFindNext(pmsdThis->pdnmlModels, NULL, i2Vec[iIndex]);
3198       	if (pdnmlThis)
3199 	{
3200 	 pmldThis = (PMLD) pdnmlThis->data.ptrvalue;
3201 	 if (pmldThis)
3202 	 if (pmldThis->iType !=  Model_type_ncbi_vector) /* skip vector models */
3203 	   {
3204 	       if (pmldThis->iType == Model_type_pdb_model) iPDBCount++;
3205 	   }
3206  	}
3207        }
3208     if ((iPDBCount < 2) && (bKinRender & (Byte) KIN_MULTANIM))
3209       {  /* force KIN_MULTANIM OFF if too few PDB models */
3210         bKinRender =  (Byte) (bKinRender - (Byte) KIN_MULTANIM);
3211       }
3212     if (bKinRender & (Byte) KIN_MULTANIM) /* Do as an animation series */
3213        {
3214           iColor = KIN_COLOR_NUMBER;  /* no choices here */
3215  	  fprintf(pFile, "@kinemage 1\n");
3216 	  fprintf(pFile, "@caption\n");
3217 	  fprintf(pFile, "PDB Models - Animation Series\n\n\n Try the A Key\n");
3218 	  fflush(pFile);
3219 	  for (iIndex = 0; iIndex < iNumModels; iIndex++)
3220 	    {
3221 		ProgMon("Writing Kinemage Animation");
3222 /*	        printf("model %d\n", i2Vec[iIndex]); */
3223 	       iTest = WriteKinAnimate(i2Vec[iIndex],  pdnmsThis, pFile,  iColor,  bKinRender, pcComposition);
3224 	    }
3225        }
3226     else
3227     for (iIndex = 0; iIndex < iNumModels; iIndex++)
3228        {  /* otherwise separate kinemages */
3229 	  ProgMon("Writing Kinemage");
3230 	  fprintf(pFile, "@kinemage %d\n", (int)iIndex);
3231 	  fprintf(pFile, "@caption\n");
3232 	  fprintf(pFile, "\nMMDB Model Number %d. \n", (int)i2Vec[iIndex]);
3233 	  fflush(pFile);
3234 	  iTest = WriteKinModel(i2Vec[iIndex], pdnmsThis, pFile,  iColor,  bKinRender, pcComposition);
3235        }
3236     fflush(pFile);
3237     if (pcComposition) MemFree(pcComposition);
3238     return iTest;
3239 }
3240 
3241 
WriteKinOneModel(PDNMS pdnmsThis,FILE * pFile,Int2 iColor,Byte bKinRender,Int2 iModel)3242 Int2 LIBCALL WriteKinOneModel(PDNMS pdnmsThis,  FILE *pFile, Int2 iColor, Byte bKinRender, Int2 iModel)
3243 {
3244     Int2 iRet = FALSE;
3245     iRet = WriteKinModelList(pdnmsThis, pFile,  iColor,  bKinRender, 1, (Int2Ptr) &iModel);
3246     return iRet;
3247 }
3248 
3249 
WriteKinAllModel(PDNMS pdnmsThis,FILE * pFile,Int2 iColor,Byte bKinRender)3250 Int2 LIBCALL WriteKinAllModel(PDNMS pdnmsThis, FILE *pFile, Int2 iColor, Byte bKinRender)
3251 {
3252    Int2Ptr i2Vec = NULL;
3253     PDNML pdnmlThis = NULL;
3254     PMSD pmsdThis = NULL;
3255     PMLD pmldThis = NULL;
3256     Int2 iCount = 0;
3257     Int2 iRet = 0;
3258     Int2 iPDBCount = 0;
3259 
3260     pmsdThis = (PMSD)  PFBFromDN(pdnmsThis);
3261     if (!(pmsdThis->bMe == (Byte) AM_MSD)) return iRet;
3262 
3263     pdnmlThis = pmsdThis->pdnmlModels; /* the linked-list of models */
3264     if (pdnmlThis)
3265       while (pdnmlThis)
3266        {
3267 	 pmldThis = (PMLD) pdnmlThis->data.ptrvalue;
3268 	 if (pmldThis)
3269 	 if (pmldThis->iType !=  Model_type_ncbi_vector) /* skip vector models */
3270 	   {
3271 	       if (pmldThis->iType == Model_type_pdb_model) iPDBCount++;
3272 	       iCount++;
3273 	   }
3274          pdnmlThis = pdnmlThis->next;
3275        }
3276     else return 0;  /* no models */
3277     if ((iPDBCount < 2) && (bKinRender & (Byte) KIN_MULTANIM))
3278       {  /* force KIN_MULTANIM OFF if too few models */
3279         bKinRender =  (Byte) (bKinRender - (Byte) KIN_MULTANIM);
3280       }
3281     if (bKinRender & (Byte) KIN_MULTANIM)
3282        i2Vec = I2Vector(0, iCount);
3283     else
3284        i2Vec = I2Vector(0, iPDBCount);
3285     if (!i2Vec) return iRet;
3286     iCount = 0;
3287     pdnmlThis = pmsdThis->pdnmlModels;
3288     while (pdnmlThis)
3289 	{  /* copy the model id's into the vector */
3290  	 pmldThis = (PMLD) pdnmlThis->data.ptrvalue;
3291 	 if (pmldThis)
3292 	 if (pmldThis->iType != Model_type_ncbi_vector) /* skip vector models */
3293 	   {
3294 	     if ((bKinRender & (Byte) KIN_MULTANIM))
3295 	       {
3296 		 if (pmldThis->iType == Model_type_pdb_model)
3297 		   { /* just do the PDB models */
3298 		    i2Vec[iCount] = pdnmlThis->choice;
3299 		    iCount++;
3300 		   }
3301 	       }
3302 	     else
3303 	       {  /* pick the rest */
3304 		i2Vec[iCount] = pdnmlThis->choice;
3305 	        iCount++;
3306 	       }
3307 	   }
3308 
3309 	    pdnmlThis = pdnmlThis->next;
3310 	}
3311 #ifdef _DEBUG_0
3312    printf("%d models to do \n", iCount);
3313 #endif
3314 
3315     iRet = WriteKinModelList(pdnmsThis, pFile,  iColor,  bKinRender, iCount, i2Vec);
3316     I2VectorFree(i2Vec, 0);
3317     return iRet;
3318 }
3319 
3320 
3321 
3322 
3323 /* BRANDON - Here's your code - Go Crazy! */
3324 
WriteStrucHTMLHeader(PDNMS pdnmsThis,FILE * pFile)3325 static void WriteStrucHTMLHeader(PDNMS pdnmsThis,  FILE *pFile)
3326 {
3327 
3328    Int4 depyear, depday;
3329    PMSD pmsdThis = NULL;
3330    BiostrucSourcePtr pbssThis = NULL;
3331    ValNodePtr pvnThis = NULL;
3332    BiostrucHistoryPtr pbshThis = NULL;
3333    CharPtr pcAuthors = NULL;
3334 
3335    if (!pdnmsThis) return;
3336    pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
3337    pvnThis = ValNodeFindNext(pmsdThis->pbsBS->descr,NULL,BiostrucDescr_history);
3338    if (pvnThis)
3339      {
3340       pbshThis = (BiostrucHistoryPtr) pvnThis->data.ptrvalue;
3341       pbssThis = pbshThis->data_source;
3342      }
3343    if (!pmsdThis->pcPDBName) pmsdThis->pcPDBName = StringSave("1UNK");
3344    fprintf(pFile,"Structure Summary\n\n");
3345    fprintf(pFile,"Contents:\n%s\n\n", pmsdThis->pcChemName);
3346    fflush(pFile);
3347    fprintf(pFile,"MMDB Accession:\n%ld\n\n", (long) pmsdThis->iMMDBid);
3348    fprintf(pFile,"PDB Accession:\n%s\n\n", pmsdThis->pcPDBName);
3349    fflush(pFile);
3350    if (pbssThis)
3351      {
3352    	depyear = pbssThis->database_entry_date->data[1];
3353    	depday = pbssThis->database_entry_date->data[3];
3354 
3355     if(pbssThis->database_entry_date->data[2] >= 1)
3356    	fprintf(pFile,"PDB Deposition:\n%2d-%3s-%02d\n\n",
3357                    (int) depday,
3358                    NCBI_months[pbssThis->database_entry_date->data[2]-1],
3359                    (int) depyear%100);
3360      }
3361   fprintf(pFile,"Class:\n%s\n\n", pmsdThis->pcPdbClass);
3362   fflush(pFile);
3363   fprintf(pFile,"Source:\n%s\n\n", pmsdThis->pcPdbSource);
3364   fflush(pFile);
3365   pcAuthors =  AuthorListPDB(pmsdThis->pbsBS) ;
3366   if (pcAuthors)
3367     {
3368       fprintf(pFile,"Authors:\n%s\n\n", pcAuthors);
3369       fflush(pFile);
3370       MemFree(pcAuthors);
3371     }
3372 
3373   return;
3374 }
3375 
WriteStrucHTMLSeq(PDNMS pdnmsThis,FILE * pFile)3376 NLM_EXTERN void WriteStrucHTMLSeq(PDNMS pdnmsThis,  FILE *pFile)
3377 {  /* writes out the sequence in UPPERCASE 3 Letter Code PDB Style, 10 per line  */
3378    /* some of this is from "legacy code" from Hitomi's stuff */
3379    Int4 resnum,linecnt,rest,curResCnt,i;
3380    CharPtr resnam;
3381    PDNMG pdnmgRes;
3382    PMSD pmsdThis = NULL;
3383    PDNMM pdnmmThis = NULL;
3384    PMMD pmmdThis = NULL;
3385    PMGD pmgdThis = NULL;
3386    CharPtr pcKinMolName = NULL;
3387    CharPtr pcTest = NULL;
3388    CharPtr pcComp = NULL;
3389    Int4 iLen = 0;
3390 
3391     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
3392     pdnmmThis = pmsdThis->pdnmmHead; /* the top of the molecule list */
3393 
3394     fprintf(pFile, "\nSequence(s) as they appear in the PDB file.\n");
3395     fflush(pFile);
3396     while (pdnmmThis) /* walk the molecules individually */
3397       {
3398 	pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
3399 	switch((int)pmmdThis->bWhat)
3400 	 {
3401 	  case AM_HET:
3402       case AM_POLY:
3403       case AM_ION:
3404 		pdnmgRes = pmmdThis->pdnmgHead;
3405 		pmgdThis = (PMGD) pdnmgRes->data.ptrvalue;
3406 		if (pmgdThis->pcPDBComment)
3407 		  {
3408             if(StrCmp(pmgdThis->pcPDBComment, "") != 0)
3409 		        fprintf(pFile,"\nHeterogen Name: %s\n",
3410 				    pmgdThis->pcPDBComment);
3411 		  }
3412 	        break;
3413 	  case AM_DNA:
3414 	  case AM_RNA:
3415          case AM_PROT:
3416 		resnum = pmmdThis->iResCount;
3417 		linecnt = 1;
3418  	 	rest = resnum;
3419 	 	pdnmgRes = pmmdThis->pdnmgHead;
3420 	        pcKinMolName = GetKinMolName(pmmdThis);
3421 		fprintf(pFile,"\nSequence {%d %s %s} has %d residues:\n",
3422 				(int)pdnmmThis->choice,
3423 				pcKinMolName,
3424 				pmmdThis->pcMolName,
3425 				(int)resnum);
3426 
3427 			fflush(pFile);
3428 	 	while ((rest > 0) && (pdnmgRes != NULL))
3429 	 	  {
3430 
3431 			linecnt++;
3432 			if (rest > 10)
3433 	       		    curResCnt = 10;
3434 			else
3435 			    curResCnt = rest;
3436 			i = 0;
3437 			while ((i < curResCnt) && (pdnmgRes != NULL))
3438 			 {
3439 			    pmgdThis = (PMGD) pdnmgRes->data.ptrvalue;
3440 			    resnam = StringSave(pmgdThis->pcGraphName);
3441 			    if (!resnam)
3442 				resnam = StringSave("UNK");
3443 			    pcTest = NULL;
3444 			    if (pmgdThis->bWhat & (Byte) RES_AA)
3445   			     {
3446 				pcTest = StringChr(NCBIstdaaUC,pmgdThis->pcIUPAC[0]);
3447 
3448 			     }
3449 			    if ((pmgdThis->bWhat & (Byte) RES_RNA) || (pmgdThis->bWhat & (Byte) RES_DNA))
3450 			     {
3451 				pcTest = StringChr(NCBI4naUC,pmgdThis->pcIUPAC[0]);
3452 				if (pcTest)
3453 				  {
3454 				      pcComp = NCBI4naUC;
3455 				      iLen = 0;
3456 				      while ((pcComp != pcTest) && (pcComp))
3457 				        {
3458 					    iLen++;
3459 					    pcComp = (CharPtr) &pcComp[1];
3460 					}
3461 				      pcTest = (CharPtr) &NCBI4naLC[iLen];
3462 				  }
3463 			     }
3464 			    if (!pcTest) pcTest = "?";
3465 		            if ((pmgdThis->bWhat & (Byte) DICT_LOCAL) &&
3466 			        ((resnam[0]=='D') || (resnam[0]=='R')) &&
3467 				(resnam[1]=='N') &&
3468 				(resnam[2]=='A'))
3469 				{
3470 				    fprintf(pFile,"%3s ",(CharPtr)&resnam[3]);
3471 				    fflush(pFile);
3472 				}
3473 			    else
3474 			        {
3475 				    if (StringLen(resnam) > 3) resnam[3] = '\0';
3476 					/* truncate SER COOH dict. */
3477 				    fprintf(pFile,"%3s ",resnam);
3478 				    fflush(pFile);
3479 				}
3480 			    if (resnam) MemFree(resnam);
3481 			    i++;
3482 			    pdnmgRes = pdnmgRes->next;
3483 			  }
3484 			rest -= curResCnt;
3485  			fprintf(pFile," \n");
3486 			fflush(pFile);
3487 		  } /* while pdnmgRes */
3488 		break;
3489 	  default:
3490 	    ;
3491 	 } /* switch */
3492 	 pdnmmThis = pdnmmThis->next;
3493       } /* while pdnmmThis */
3494     return;
3495 }
3496 
3497 
WriteStructSummary(PDNMS pdnmsThis,FILE * pFile)3498 Int2 LIBCALL WriteStructSummary(PDNMS pdnmsThis,  FILE *pFile)
3499 {
3500    WriteStrucHTMLHeader(pdnmsThis, pFile);
3501    WriteStrucHTMLSeq(pdnmsThis, pFile);
3502    return 1;
3503 }
3504 
3505 
3506 
3507 /**********************************************/
3508 /***Model to FASTA file ***********************/
3509 
3510 
DoSeq(PFB pfbThis,Int4 iModel,Int4 iIndex,Pointer ptr)3511 static void LIBCALLBACK DoSeq(PFB pfbThis, Int4 iModel, Int4 iIndex, Pointer ptr)
3512 {
3513   FILE *pFile = NULL;
3514   PMGD pmgdRes = NULL;
3515 
3516   if (!pfbThis) return;
3517   if (ptr) pFile = (FILE *) ptr;
3518     else return;
3519 
3520     if (pfbThis->bMe == AM_MGD)
3521       {
3522           /* cast to the correct PMGD pointer type */
3523           pmgdRes = (PMGD) pfbThis;
3524           /* prints 1 letter code  */
3525           if (pmgdRes->pcIUPAC)
3526             fprintf(pFile, "%c", pmgdRes->pcIUPAC[0]);
3527           if (pmgdRes->pdnmgLink->choice % iIndex == 0)
3528           fprintf(pFile,"\n");
3529       }
3530 }
3531 
3532 
WriteFASTAMolecule(PDNMM pdnmmThis,FILE * File,Int4 LineLen)3533 void LIBCALL WriteFASTAMolecule(PDNMM pdnmmThis, FILE *File, Int4 LineLen)
3534   {
3535    PMMD pmmdThis = NULL;
3536    PMSD pmsdThis = NULL;
3537    Int4 iTest =0;
3538 
3539    if (!pdnmmThis) return;
3540    if (!File) return;
3541 
3542    if (LineLen <= 0)
3543      LineLen = 60;
3544    pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
3545    pmsdThis = ToMSDParent((PFB) pmmdThis);
3546 
3547    if (pmmdThis->iResCount > 1)
3548      {
3549        if (pmmdThis->pcMolName[0] != ' ')
3550           fprintf(File, ">gi|%ld|pdb|%s|%c Chain %c, %s, %s\n",
3551                  (long) pmmdThis->iGi, pmsdThis->pcPDBName, (char) pmmdThis->pcMolName[0],
3552 		 (char) pmmdThis->pcMolName[0],
3553                   pmsdThis->pcChemName ? pmsdThis->pcChemName : "No name",
3554                   pmsdThis->pcPdbSource ? pmsdThis->pcPdbSource : "Unknown source");
3555        else
3556           fprintf(File, ">gi|%ld|pdb|%s|%c %s, %s\n",
3557                  (long) pmmdThis->iGi, pmsdThis->pcPDBName, (char) pmmdThis->pcMolName[0],
3558 		  pmsdThis->pcChemName ? pmsdThis->pcChemName : "No name",
3559                   pmsdThis->pcPdbSource ? pmsdThis->pcPdbSource : "Unknown source");
3560        fflush(File);
3561        iTest = TraverseGraphs(pmmdThis->pdnmgHead,0,
3562                                 LineLen,File,
3563                                 (pNodeFunc)(DoSeq));
3564 
3565       fflush(File);
3566       fprintf(File, "\n");
3567       fflush(File);
3568 
3569      }
3570    return;
3571   }
3572 
3573 
WriteFASTASeqHet(PDNMS pdnmsThis,FILE * pFile)3574 void LIBCALL WriteFASTASeqHet(PDNMS pdnmsThis,  FILE *pFile)
3575 {  /* writes out the sequences and heterogen names   */
3576    PDNMG pdnmgRes;
3577    PMSD pmsdThis = NULL;
3578    PDNMM pdnmmThis = NULL;
3579    PMMD pmmdThis = NULL;
3580    PMGD pmgdThis = NULL;
3581 
3582     pmsdThis = (PMSD) pdnmsThis->data.ptrvalue;
3583     pdnmmThis = pmsdThis->pdnmmHead; /* the top of the molecule list */
3584     fprintf(pFile, "Validated Sequence(s) in FASTA format; Heterogen Names\n\n");
3585     fflush(pFile);
3586     while (pdnmmThis) /* walk the molecules individually */
3587       {
3588 	pmmdThis = (PMMD) pdnmmThis->data.ptrvalue;
3589 	switch((int)pmmdThis->bWhat)
3590 	 {
3591 	  case AM_HET:
3592                 pdnmgRes = pmmdThis->pdnmgHead;
3593 		pmgdThis = (PMGD) pdnmgRes->data.ptrvalue;
3594 		if (pmgdThis->pcPDBComment)
3595 		  {
3596 		    fprintf(pFile,"Heterogen Name: %s\n",
3597 				pmgdThis->pcPDBComment);
3598 		  }
3599 	        break;
3600          case AM_POLY:
3601 	        pdnmgRes = pmmdThis->pdnmgHead;
3602 		pmgdThis = (PMGD) pdnmgRes->data.ptrvalue;
3603 		if (pmgdThis->pcPDBComment)
3604 		  {
3605 		    fprintf(pFile,"Biopolymer {%d het} Name: %s\n",
3606 				(int)pdnmmThis->choice,
3607 				pmgdThis->pcPDBComment);
3608 		  }
3609 	        break;
3610 	  case AM_DNA:
3611 	  case AM_RNA:
3612          case AM_PROT:
3613 		 WriteFASTAMolecule(pdnmmThis, pFile, 60);
3614                  fflush(pFile);
3615 		 fprintf(pFile, "\n");
3616 		break;
3617 	  default:
3618 	    ;
3619 	 } /* switch */
3620 	 pdnmmThis = pdnmmThis->next;
3621       } /* while pdnmmThis */
3622     return ;
3623 }
3624