1 /* @source ajpdb **************************************************************
2 **
3 ** AJAX low-level functions for handling protein structural data.
4 ** For use with the Atom, Chain and Pdb objects defined in ajpdb.h
5 ** Also for use with Hetent, Het, Vdwres, Vdwall, Cmap and Pdbtosp objects
6 ** (also defined in ajpdb.h).
7 ** Includes functions for reading and writing ccf (clean coordinate file)
8 ** format.
9 **
10 ** @author Copyright (C) 2004 Jon Ison (jison@hgmp.mrc.ac.uk)
11 ** @version $Revision: 1.58 $
12 ** @modified $Date: 2012/12/07 10:16:44 $ by $Author: rice $
13 ** @@
14 **
15 ** This library is free software; you can redistribute it and/or
16 ** modify it under the terms of the GNU Lesser General Public
17 ** License as published by the Free Software Foundation; either
18 ** version 2.1 of the License, or (at your option) any later version.
19 **
20 ** This library is distributed in the hope that it will be useful,
21 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23 ** Lesser General Public License for more details.
24 **
25 ** You should have received a copy of the GNU Lesser General Public
26 ** License along with this library; if not, write to the Free Software
27 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
28 ** MA  02110-1301,  USA.
29 **
30 ******************************************************************************/
31 
32 
33 
34 
35 /* ======================================================================= */
36 /* ============================ include files ============================ */
37 /* ======================================================================= */
38 
39 #include "ajlib.h"
40 
41 #include "ajpdb.h"
42 #include "ajbase.h"
43 #include "ajfileio.h"
44 #include "ajseqwrite.h"
45 
46 #include <limits.h>
47 #include <string.h>
48 
49 
50 
51 
52 /* ======================================================================= */
53 /* ============================ private data ============================= */
54 /* ======================================================================= */
55 
56 #define CMAP_MODE_I 1
57 #define CMAP_MODE_C 2
58 
59 static AjPStr pdbGStrline = NULL;       /* Line of text     */
60 static AjPStr pdbGStrtemp_id = NULL;    /* Temp. protein id */
61 static AjPStr pdbGStrtemp_domid = NULL; /* Temp. domain id  */
62 static AjPStr pdbGStrtemp_ligid = NULL; /* Temp. ligand id  */
63 static AjPStr pdbGStrdesc = NULL;       /* Ligand description, SITES output
64                                          * only */
65 static AjPStr pdbGStrtype = NULL;       /* Type of contact  */
66 static AjPStr pdbGStrtmpstr = NULL;     /* Housekeeping */
67 
68 
69 
70 
71 /* ======================================================================= */
72 /* ================= Prototypes for private functions ==================== */
73 /* ======================================================================= */
74 
75 static ajint pdbSortPdbtospPdb(const void *item1, const void *item2);
76 
77 
78 
79 
80 /* ======================================================================= */
81 /* ========================== private functions ========================== */
82 /* ======================================================================= */
83 
84 
85 
86 
87 /* @funcstatic pdbSortPdbtospPdb **********************************************
88 **
89 ** Function to compare AJAX PDB to Swiss-Prot objects by Pdb member.
90 ** Usually called by ajPdbtospReadAllNew.
91 **
92 ** @param [r] item1 [const void*] AJAX PDB to Swiss-Prot address 1
93 ** @param [r] item2 [const void*] AJAX PDB to Swiss-Prot address 2
94 ** @see ajListSort
95 **
96 ** @return [ajint] -1 if Pdb1 should sort before Pdb2,
97 **                 +1 if the Pdb2 should sort first.
98 **                  0 if they are identical in length and content.
99 **
100 ** @release 2.9.0
101 ** @@
102 ******************************************************************************/
103 
pdbSortPdbtospPdb(const void * item1,const void * item2)104 static ajint pdbSortPdbtospPdb(const void *item1, const void *item2)
105 {
106     AjPPdbtosp pdbtosp1 = *(AjOPdbtosp *const *) item1;
107     AjPPdbtosp pdbtosp2 = *(AjOPdbtosp *const *) item2;
108 
109     return ajStrCmpS(pdbtosp1->Pdb, pdbtosp2->Pdb);
110 }
111 
112 
113 
114 
115 /* ======================================================================= */
116 /* =========================== constructors ============================== */
117 /* ======================================================================= */
118 
119 
120 
121 
122 /* @section Constructors ******************************************************
123 **
124 ** All constructors return a pointer to a new instance. It is the
125 ** responsibility of the user to first destroy any previous instance. The
126 ** target pointer does not need to be initialised to NULL, but it is good
127 ** programming practice to do so anyway.
128 **
129 ******************************************************************************/
130 
131 
132 
133 
134 /* @func ajPdbtospReadAllRawNew ***********************************************
135 **
136 ** Reads the swissprot:pdb equivalence table available at URL (1)
137 **  (1) http://www.expasy.ch/cgi-bin/lists?pdbtosp.txt
138 ** and returns the data as a list of Pdbtosp objects.
139 **
140 ** @param [u] inf [AjPFile] Input file
141 **
142 ** @return [AjPList] AJAX List of AJAX PDB to Swiss-Prot (AjPPdbtosp) objects
143 **
144 ** @release 2.9.0
145 ** @@
146 **
147 ******************************************************************************/
148 
ajPdbtospReadAllRawNew(AjPFile inf)149 AjPList ajPdbtospReadAllRawNew(AjPFile inf)
150 {
151     AjPList list = NULL;        /* List of Pdbtosp objects to return */
152     AjPPdbtosp pdbtosp = NULL;  /* Temp. pointer to Pdbtosp object */
153     AjPStr pdb = NULL;          /* PDB identifier */
154     AjPStr spr = NULL;          /* Swissprot identifier */
155     AjPStr acc = NULL;          /* Accession number */
156     AjPStr line = NULL;         /* Line from file */
157     AjPStr token = NULL;        /* Token from line */
158     const AjPStr subtoken = NULL;       /* Token from line */
159     AjPList acclist = NULL;     /* List of accession numbers */
160     AjPList sprlist = NULL;     /* List of swissprot identifiers */
161     ajint n = 0;                /* No. of accession numbers for current pdb
162                                  * code */
163     AjBool ok = ajFalse;        /* True if "____  _" has been found and we
164                                  * can start parsing */
165     AjBool done_1st = ajFalse;  /* True if the first line of data has been
166                                  * parsed */
167 
168 
169     /* Memory allocation */
170     line = ajStrNew();
171     token = ajStrNew();
172     subtoken = ajStrNew();
173     pdb = ajStrNew();
174     acclist = ajListstrNew();
175     sprlist = ajListstrNew();
176     list = ajListNew();
177 
178 
179     /* Read lines from file */
180     while (ajReadlineTrim(inf, &line))
181     {
182         if (ajStrPrefixC(line, "____  _"))
183         {
184             ok = ajTrue;
185             continue;
186         }
187 
188 
189         if (!ok)
190             continue;
191 
192         if (ajStrMatchC(line, ""))
193             break;
194 
195 
196         /* Read in pdb code first.  Then tokenise by ':', discard the first
197          * token, then tokenise the second token by ',', parsing out the
198          * swissprot codes and accession numbers from the subtokens */
199 
200 
201         /* Make sure this is a line containing the pdb code */
202         if ((ajStrFindC(line, ":") != -1))
203         {
204             if (done_1st)
205             {
206                 pdbtosp = ajPdbtospNew(0);
207                 ajStrAssignS(&pdbtosp->Pdb, pdb);
208                 pdbtosp->Number = n;
209                 ajListToarray(acclist, (void ***) &pdbtosp->Acc);
210                 ajListToarray(sprlist, (void ***) &pdbtosp->Spr);
211                 ajListPushAppend(list, (void *) pdbtosp);
212 
213                 ajListstrFree(&acclist);
214                 ajListstrFree(&sprlist);
215                 acclist = ajListstrNew();
216                 sprlist = ajListstrNew();
217 
218                 n = 0;
219             }
220 
221             ajFmtScanS(line, "%S", &pdb);
222 
223             ajStrParseC(line, ":");
224             ajStrAssignS(&token, ajStrParseC(NULL, ":"));
225 
226             done_1st = ajTrue;
227         }
228         else
229         {
230             ajStrAssignS(&token, line);
231         }
232 
233         spr = ajStrNew();
234         acc = ajStrNew();
235         ajFmtScanS(token, "%S (%S", &spr, &acc);
236 
237         if (ajStrSuffixC(acc, "),"))
238             ajStrCutEnd(&acc, 2);
239         else
240             ajStrCutEnd(&acc, 1);
241 
242         ajListstrPushAppend(acclist, acc);
243         ajListstrPushAppend(sprlist, spr);
244         n++;
245 
246         ajStrParseC(token, ",");
247 
248         while ((subtoken = ajStrParseC(NULL, ",")))
249         {
250             spr = ajStrNew();
251             acc = ajStrNew();
252 
253             ajFmtScanS(subtoken, "%S (%S", &spr, &acc);
254 
255             if (ajStrSuffixC(acc, "),"))
256                 ajStrCutEnd(&acc, 2);
257             else
258                 ajStrCutEnd(&acc, 1);
259 
260             ajListstrPushAppend(acclist, acc);
261             ajListstrPushAppend(sprlist, spr);
262             n++;
263         }
264     }
265 
266     /* Data for last pdb code ! */
267     pdbtosp = ajPdbtospNew(0);
268     ajStrAssignS(&pdbtosp->Pdb, pdb);
269     pdbtosp->Number = n;
270 
271     ajListToarray(acclist, (void ***) &pdbtosp->Acc);
272     ajListToarray(sprlist, (void ***) &pdbtosp->Spr);
273     ajListPushAppend(list, (void *) pdbtosp);
274     ajListstrFree(&acclist);
275     ajListstrFree(&sprlist);
276 
277     ajStrDel(&line);
278     ajStrDel(&token);
279     ajStrDel(&pdb);
280     ajListstrFree(&acclist);
281     ajListstrFree(&sprlist);
282 
283     return list;
284 }
285 
286 
287 
288 
289 /* @func ajPdbtospReadNew *****************************************************
290 **
291 ** Read a Pdbtosp object from a file in embl-like format (see documentation
292 ** for DOMAINATRIX "pdbtosp" application).
293 **
294 ** @param [u] inf [AjPFile] Input file stream
295 ** @param [r] entry [const AjPStr] Pdb id
296 **
297 ** @return [AjPPdbtosp] True on success
298 **
299 ** @release 2.9.0
300 ** @@
301 ******************************************************************************/
302 
ajPdbtospReadNew(AjPFile inf,const AjPStr entry)303 AjPPdbtosp ajPdbtospReadNew(AjPFile inf, const AjPStr entry)
304 {
305     return ajPdbtospReadCNew(inf, ajStrGetPtr(entry));
306 }
307 
308 
309 
310 
311 /* @func ajPdbtospReadCNew ****************************************************
312 **
313 ** Read a Pdbtosp object from a file in embl-like format.  Memory for the
314 ** object is allocated.
315 **
316 ** @param [u] inf   [AjPFile] Input file stream
317 ** @param [r] entry [const char*]   Pdb id
318 **
319 ** @return [AjPPdbtosp] True on success
320 **
321 ** @release 2.9.0
322 ** @@
323 ******************************************************************************/
324 
ajPdbtospReadCNew(AjPFile inf,const char * entry)325 AjPPdbtosp ajPdbtospReadCNew(AjPFile inf, const char *entry)
326 {
327     AjPPdbtosp pdbtosp = NULL;
328 
329     AjPStr line = NULL;
330     AjPStr tentry = NULL;
331     AjPStr pdb = NULL;
332     AjBool ok = ajFalse;
333     ajint n = 0;
334     ajint i = 0;
335 
336     line = ajStrNew();
337     tentry = ajStrNew();
338     pdb = ajStrNew();
339 
340     ajStrAssignC(&tentry, entry);
341     ajStrFmtUpper(&tentry);
342 
343     while ((ok = ajReadlineTrim(inf, &line)))
344     {
345         if (!ajStrPrefixC(line, "EN   "))
346             continue;
347 
348         ajFmtScanS(line, "%*S %S", &pdb);
349 
350         if (ajStrMatchWildS(pdb, tentry))
351             break;
352     }
353 
354     if (!ok)
355     {
356         ajStrDel(&line);
357         ajStrDel(&tentry);
358         ajStrDel(&pdb);
359 
360         return NULL;
361     }
362 
363     while (ok && !ajStrPrefixC(line, "//"))
364     {
365         if (ajStrPrefixC(line, "XX"))
366         {
367             ok = ajReadlineTrim(inf, &line);
368             continue;
369         }
370         else if (ajStrPrefixC(line, "NE"))
371         {
372             ajFmtScanS(line, "%*S %d", &n);
373             pdbtosp = ajPdbtospNew(n);
374             ajStrAssignS(&pdbtosp->Pdb, pdb);
375         }
376         else if (ajStrPrefixC(line, "IN"))
377         {
378             ajFmtScanS(line, "%*S %S %*S %S", &pdbtosp->Spr[i],
379                        &pdbtosp->Acc[i]);
380             i++;
381         }
382 
383         ok = ajReadlineTrim(inf, &line);
384     }
385 
386     ajStrDel(&line);
387     ajStrDel(&tentry);
388     ajStrDel(&pdb);
389 
390     return pdbtosp;
391 }
392 
393 
394 
395 
396 /* @func ajPdbtospReadAllNew **************************************************
397 **
398 ** Read all the Pdbtosp objects in a file in embl-like format (see
399 ** documentation for DOMAINATRIX "pdbtosp" application) and writes a list of
400 ** these objects. It then sorts the list by PDB id.
401 **
402 ** @param [u] inf [AjPFile] Input file stream
403 **
404 ** @return [AjPList] List of Pdbtosp objects.
405 **
406 ** @release 2.9.0
407 ** @@
408 ******************************************************************************/
409 
ajPdbtospReadAllNew(AjPFile inf)410 AjPList ajPdbtospReadAllNew(AjPFile inf)
411 {
412     AjPList list = NULL;
413 
414     AjPPdbtosp pdbtosp = NULL;
415 
416     /* Check args and allocate list if necessary */
417     if (!inf)
418         return NULL;
419 
420     list = ajListNew();
421 
422     while ((pdbtosp = ajPdbtospReadCNew(inf, "*")))
423         ajListPush(list, (void *) pdbtosp);
424 
425     ajListSort(list, &pdbSortPdbtospPdb);
426 
427     return list;
428 }
429 
430 
431 
432 
433 /* @func ajCmapReadINew *******************************************************
434 **
435 ** Read a Cmap object from a file in CON  format (see
436 ** documentation for DOMAINATRIX "contacts" application). Takes the chain
437 ** identifier as an integer. If the arguments mod and chn are both 0, the
438 ** function will read the next Cmap in the file.
439 **
440 ** @param [u] inf     [AjPFile]  Input file stream
441 ** @param [r] chn     [ajint]    Chain number
442 ** @param [r] mod     [ajint]    Model number
443 **
444 ** @return [AjPCmap] Pointer to new Cmap object.
445 ** @category new [AjPCmap] Cmap constructor from reading file in CON
446 **           format (see documentation for the EMBASSY DOMAINATRIX package).
447 **
448 ** @release 2.9.0
449 ** @@
450 ******************************************************************************/
451 
ajCmapReadINew(AjPFile inf,ajint chn,ajint mod)452 AjPCmap ajCmapReadINew(AjPFile inf, ajint chn, ajint mod)
453 {
454     AjPCmap cmap = NULL;
455 
456     if (!(cmap = ajCmapReadNew(inf, CMAP_MODE_I, chn, mod)))
457         return NULL;
458 
459     return cmap;
460 }
461 
462 
463 
464 
465 /* @func ajCmapReadCNew *******************************************************
466 **
467 ** Read a Cmap object from a file in CON format (see
468 ** documentation for DOMAINATRIX "contacts" application). Takes the chain
469 ** identifier as a character.
470 **
471 ** @param [u] inf     [AjPFile]  Input file stream
472 ** @param [r] chn     [char]     Chain number
473 ** @param [r] mod     [ajint]    Model number
474 **
475 ** @return [AjPCmap]   Pointer to new Cmap object.
476 ** @category new [AjPCmap] Cmap constructor from reading file in CON
477 **              format (see documentation for the EMBASSY DOMAINATRIX package).
478 **
479 ** @release 2.9.0
480 ** @@
481 ******************************************************************************/
482 
ajCmapReadCNew(AjPFile inf,char chn,ajint mod)483 AjPCmap ajCmapReadCNew(AjPFile inf, char chn, ajint mod)
484 {
485     AjPCmap cmap = NULL;
486 
487     if (!(cmap = ajCmapReadNew(inf, CMAP_MODE_C, (ajint) chn, mod)))
488         return NULL;
489 
490     return cmap;
491 }
492 
493 
494 
495 
496 /* @func ajCmapReadAllNew *****************************************************
497 **
498 ** Read every Cmap object from a file in CON format (see
499 ** documentation for DOMAINATRIX "contacts" application) and returns a list
500 ** of these objects.
501 **
502 ** @param [u] inf     [AjPFile]  Input file stream
503 **
504 ** @return [AjPList]   List of Cmap objects.
505 *** @@
506 **
507 ** @release 3.0.0
508 ******************************************************************************/
509 
ajCmapReadAllNew(AjPFile inf)510 AjPList ajCmapReadAllNew(AjPFile inf)
511 {
512     AjPList list = NULL;
513     AjPCmap cmap = NULL;
514 
515     list = ajListNew();
516 
517     while ((cmap = ajCmapReadNew(inf, CMAP_MODE_I, 0, 0)))
518         ajListPushAppend(list, cmap);
519 
520     return list;
521 }
522 
523 
524 
525 
526 /* @func ajCmapReadNew ********************************************************
527 **
528 ** Read a Cmap object from a file in CON format (see
529 ** documentation for DOMAINATRIX "contacts" application). This is not
530 ** usually called by the user, who uses ajCmapReadINew or ajCmapReadCNew
531 ** instead.  If mode==CMAP_MODE_I, chn==0 and  mod==0, the function will
532 ** read the next Cmap in the file.
533 **
534 ** @param [u] inf     [AjPFile]  Input file stream.
535 ** @param [r] mode    [ajint]    Mode, either CMAP_MODE_I (treat chn arg as
536 **                               an integer) or CMAP_MODE_C (treat chn arg as
537 **                               a character).
538 ** @param [r] chn     [ajint]    Chain identifier / number.
539 ** @param [r] mod     [ajint]    Model number.
540 **
541 ** @return [AjPCmap] True on success (an object read)
542 ** @category new [AjPCmap] Cmap constructor from reading file in CON
543 **              format (see documentation for the EMBASSY DOMAINATRIX package).
544 **
545 ** @release 2.9.0
546 ** @@
547 ******************************************************************************/
548 
ajCmapReadNew(AjPFile inf,ajint mode,ajint chn,ajint mod)549 AjPCmap ajCmapReadNew(AjPFile inf, ajint mode, ajint chn, ajint mod)
550 
551 {
552     AjPCmap cmap = NULL;
553     const AjPStr token = NULL;  /* For parsing      */
554 
555     ajint smcon = 0;            /* No. of SM contacts       */
556     ajint licon = 0;            /* No. of LI contacts       */
557     ajint x = 0;                /* No. of first residue making contact */
558     ajint y = 0;                /* No. of second residue making contact */
559     ajint md = -1;              /* Model number   */
560     ajint cn1 = -1;             /* Chain number 1 */
561     ajint cn2 = -1;             /* Chain number 2 */
562     char id1 = -1;              /* Chain id 1     */
563     char id2 = -1;              /* Chain id 2     */
564     ajint nres1 = 0;            /* No. of residues in domain / chain 1 */
565     ajint nres2 = 0;            /* No. of residues in domain / chain 2 */
566     AjPStr seq1 = NULL;         /* Sequence 1 */
567     AjPStr seq2 = NULL;         /* Sequence 2 */
568 
569     AjBool idok = ajFalse;      /* If the required chain has been found */
570 
571     ajint en;                   /* Entry number. */
572     ajint ns;                   /* No. of sites, SITES output only */
573     ajint sn;                   /* Site number, SITES output only */
574 
575     /* Check args */
576     if (!inf)
577     {
578         ajWarn("Invalid args to ajCmapReadNew");
579         return NULL;
580     }
581 
582     /* Convert '_' chain identifiers to '.' if necessary */
583     if (mode == CMAP_MODE_C)
584         if (chn == '_')
585             chn = '.';
586 
587     /* Initialise strings */
588     if (!pdbGStrline)
589     {
590         pdbGStrline = ajStrNew();
591         pdbGStrtemp_id = ajStrNew();
592         pdbGStrtemp_domid = ajStrNew();
593         pdbGStrtemp_ligid = ajStrNew();
594         pdbGStrdesc = ajStrNew();
595         pdbGStrtmpstr = ajStrNew();
596     }
597 
598     /* Start of main loop */
599     while ((ajReadlineTrim(inf, &pdbGStrline)))
600     {
601         /* // */
602         if (ajStrPrefixC(pdbGStrline, "//"))
603         {
604             /* If the delimiter between entries is found and cmap is
605              * non-NULL, i.e. has been allocated, the function should return. */
606             ajStrDel(&seq1);
607             ajStrDel(&seq2);
608 
609             return cmap;
610         }
611 
612         /* SI */
613         else if (ajStrPrefixC(pdbGStrline, "SI"))
614         {
615             token = ajStrParseC(pdbGStrline, ";");
616             ajFmtScanS(token, "%*s %*s %d", &sn);
617 
618             token = ajStrParseC(NULL, ";");
619             ajFmtScanS(token, "%*s %d", &ns);
620         }
621 
622         /* EN */
623         else if (ajStrPrefixC(pdbGStrline, "EN"))
624         {
625             ajFmtScanS(pdbGStrline, "%*s %*c%d", &en);
626         }
627 
628         /* TY */
629         else if (ajStrPrefixC(pdbGStrline, "TY"))
630         {
631             ajFmtScanS(pdbGStrline, "%*s %S", &pdbGStrtype);
632             ajStrSetClear(&seq1);
633             ajStrSetClear(&seq2);
634             id1 = '.';
635             id2 = '.';
636             cn1 = 0;
637             cn2 = 0;
638             nres1 = 0;
639             nres2 = 0;
640         }
641 
642         /* EX, NE records are not parsed */
643 
644         /* ID */
645         else if (ajStrPrefixC(pdbGStrline, "ID"))
646         {
647             token = ajStrParseC(pdbGStrline, ";");
648             ajFmtScanS(token, "%*s %*s %S", &pdbGStrtemp_id);
649             token = ajStrParseC(NULL, ";");
650             ajFmtScanS(token, "%*s %S", &pdbGStrtemp_domid);
651             token = ajStrParseC(NULL, ";");
652             ajFmtScanS(token, "%*s %S", &pdbGStrtemp_ligid);
653         }
654 
655         /* DE records are not parsed (SITES output) */
656         else if (ajStrPrefixC(pdbGStrline, "DE"))
657         {
658             ajStrAssignSubS(&pdbGStrdesc, pdbGStrline, 4, -1);
659         }
660 
661         /* CN */
662         else if (ajStrPrefixC(pdbGStrline, "CN"))
663         {
664             token = ajStrParseC(pdbGStrline, ";");
665 #if AJFALSE
666             ajFmtScanS(token, "%*s %*s %d", &md);
667             if (md == '.')
668                 md = 0;
669 #endif
670             ajFmtScanS(token, "%*s %*s %S", &pdbGStrtmpstr);
671 
672             if (ajStrMatchC(pdbGStrtmpstr, "."))
673                 md = 0;
674             else
675                 ajFmtScanS(pdbGStrtmpstr, "%d", &md);
676 
677             token = ajStrParseC(NULL, ";");
678             ajFmtScanS(token, "%*s %d", &cn1);
679 
680             token = ajStrParseC(NULL, ";");
681             ajFmtScanS(token, "%*s %d", &cn2);
682 
683             token = ajStrParseC(NULL, ";");
684             ajFmtScanS(token, "%*s %c", &id1);
685 
686             token = ajStrParseC(NULL, ";");
687             ajFmtScanS(token, "%*s %c", &id2);
688 
689             token = ajStrParseC(NULL, ";");
690 #if AJFALSE
691             ajFmtScanS(token, "%*s %d", &nres1);
692             if (nres1 == '.')
693                 nres1 = 0;
694 #endif
695 
696             ajFmtScanS(token, "%*s %S", &pdbGStrtmpstr);
697 
698             if (ajStrMatchC(pdbGStrtmpstr, "."))
699                 nres1 = 0;
700             else
701                 ajFmtScanS(pdbGStrtmpstr, "%d", &nres1);
702 
703 
704             token = ajStrParseC(NULL, ";");
705 #if AJFALSE
706             ajFmtScanS(token, "%*s %d", &nres2);
707             if ((char) nres2 == '.')
708                 nres2 = 0;
709 #endif
710             ajFmtScanS(token, "%*s %S", &pdbGStrtmpstr);
711 
712             if (ajStrMatchC(pdbGStrtmpstr, "."))
713                 nres2 = 0;
714             else
715                 ajFmtScanS(pdbGStrtmpstr, "%d", &nres2);
716         }
717 
718         /* S1 */
719         else if (ajStrPrefixC(pdbGStrline, "S1"))
720         {
721             while (ajReadlineTrim(inf, &pdbGStrline) &&
722                    !ajStrPrefixC(pdbGStrline, "XX"))
723                 ajStrAppendC(&seq1, ajStrGetPtr(pdbGStrline));
724 
725             ajStrRemoveWhite(&seq1);
726         }
727 
728         /* S2 */
729         else if (ajStrPrefixC(pdbGStrline, "S2"))
730         {
731             while (ajReadlineTrim(inf, &pdbGStrline) &&
732                    !ajStrPrefixC(pdbGStrline, "XX"))
733                 ajStrAppendC(&seq2, ajStrGetPtr(pdbGStrline));
734 
735             ajStrRemoveWhite(&seq2);
736         }
737 
738         /* NC */
739         else if ((ajStrPrefixC(pdbGStrline, "NC")) &&
740                  ((md == mod) || ((chn == 0) && (mod == 0) && (mode == CMAP_MODE_I))))
741         {
742             token = ajStrParseC(pdbGStrline, ";");
743             ajFmtScanS(token, "%*s %*s %d", &smcon);
744 
745             token = ajStrParseC(NULL, ";");
746             ajFmtScanS(token, "%*s %d", &licon);
747 
748             /*
749             ** The fourth conditional is to capture those few domains which
750             ** are made up from more than one chain.  For these, the chain
751             ** character passed in might be an A or a B (e.g. the character
752             ** extracted from the scop domain code) whereas the chain id given
753             ** in the contact map file will be a '.' - because of how
754             ** scopparse copes with these cases. (A '.' is also in the contact
755             ** maps for where a chain id was not specified in the original
756             ** pdb file).
757             */
758 
759             if (((cn1 == chn) && (mode == CMAP_MODE_I)) ||
760                 ((chn == 0) && (mod == 0) && (mode == CMAP_MODE_I)) ||
761                 ((toupper((int) id1) == toupper(chn)) &&
762                  (mode == CMAP_MODE_C)) ||
763                 ((toupper((int) id1) == '.') && (toupper(chn) != '.') &&
764                  (mode == CMAP_MODE_C))
765                 )
766             {
767                 idok = ajTrue;
768 
769                 /* Allocate contact map and write values */
770                 if (ajStrMatchC(pdbGStrtype, "INTER"))
771                 {
772                     if (nres1 > nres2)
773                         cmap = ajCmapNew(nres1);
774                     else
775                         cmap = ajCmapNew(nres2);
776                 }
777                 else
778                     cmap = ajCmapNew(nres1);
779 
780                 ajStrAssignS(&cmap->Id, pdbGStrtemp_id);
781                 ajStrAssignS(&cmap->Domid, pdbGStrtemp_domid);
782                 ajStrAssignS(&cmap->Ligid, pdbGStrtemp_ligid);
783 
784                 if (ajStrMatchC(pdbGStrtype, "INTRA"))
785                 {
786                     cmap->Type = ajECmapTypeIntra;
787                     cmap->Ncon = smcon;
788                 }
789                 else if (ajStrMatchC(pdbGStrtype, "INTER"))
790                 {
791                     cmap->Type = ajECmapTypeInter;
792                     cmap->Ncon = smcon;
793                 }
794                 else if (ajStrMatchC(pdbGStrtype, "LIGAND"))
795                 {
796                     cmap->Type = ajECmapTypeLigand;
797                     cmap->Ncon = licon;
798                     cmap->ns = ns;
799                     cmap->sn = sn;
800                     ajStrAssignS(&cmap->Desc, pdbGStrdesc);
801                 }
802                 else
803                     ajFatal("Unrecognised contact type");
804 
805                 cmap->Chn1 = cn1;
806                 cmap->Chn2 = cn2;
807                 cmap->Chid1 = id1;
808                 cmap->Chid2 = id2;
809                 cmap->Nres1 = nres1;
810                 cmap->Nres2 = nres2;
811                 cmap->en = en;
812 
813                 ajStrAssignS(&cmap->Seq1, seq1);
814                 ajStrAssignS(&cmap->Seq2, seq2);
815             }
816         }
817 
818         /* SM */
819         else if ((ajStrPrefixC(pdbGStrline, "SM")) &&
820                  ((md == mod) ||
821                   ((chn == 0) && (mod == 0) && (mode == CMAP_MODE_I)))
822                  && (idok))
823         {
824             ajFmtScanS(pdbGStrline, "%*s %*s %d %*c %*s %d", &x, &y);
825 
826             /* Check residue number is in range */
827             if ((x > cmap->Dim) || (y > cmap->Dim))
828                 ajFatal("Fatal attempt to write bad data in "
829                         "ajCmapReadNew\nFile: %S (%S)\nx: %d y:%d\n",
830                         ajFileGetPrintnameS(inf), pdbGStrtemp_id, x, y);
831 
832             /* Enter '1' in matrix to indicate contact */
833             ajUint2dPut(&cmap->Mat, x - 1, y - 1, 1);
834             ajUint2dPut(&cmap->Mat, y - 1, x - 1, 1);
835         }
836 
837         /* LI */
838         else if ((ajStrPrefixC(pdbGStrline, "LI")) &&
839                  ((md == mod) ||
840                   ((chn == 0) && (mod == 0) && (mode == CMAP_MODE_I)))
841                  && (idok))
842         {
843             ajFmtScanS(pdbGStrline, "%*s %*s %d", &x);
844 
845             /* Check residue number is in range */
846             if ((x > cmap->Dim))
847                 ajFatal("Fatal attempt to write bad data in "
848                         "ajCmapReadNew\nFile: %S (%S)\nx: %d\n",
849                         ajFileGetPrintnameS(inf), pdbGStrtemp_id, x);
850 
851             /* Enter '1' in matrix to indicate contact. For ligand contacts,
852              * the first row / column only is used. */
853             ajUint2dPut(&cmap->Mat, x - 1, 0, 1);
854             ajUint2dPut(&cmap->Mat, 0, x - 1, 1);
855         }
856     }
857 
858     ajStrDel(&seq1);
859     ajStrDel(&seq2);
860 
861     return cmap;
862 }
863 
864 
865 
866 
867 /* @func ajVdwallReadNew ******************************************************
868 **
869 ** Read a Vdwall object from a file in embl-like format (see documentation
870 ** for the EMBASSY DOMAINATRIX package).
871 **
872 ** @param [u] inf     [AjPFile]  Input file stream
873 **
874 ** @return [AjPVdwall] Pointer to Vdwall object.
875 ** @category new [AjPVdwall] Vdwall constructor from reading file in embl-like
876 **              format (see documentation for the EMBASSY DOMAINATRIX package).
877 **
878 ** @release 2.9.0
879 ** @@
880 ******************************************************************************/
881 
ajVdwallReadNew(AjPFile inf)882 AjPVdwall ajVdwallReadNew(AjPFile inf)
883 {
884     AjPVdwall vdwall = NULL;
885     AjPStr line = NULL;         /* Line of text */
886     ajint nres = 0;             /* No. residues */
887     ajint natm = 0;             /* No. atoms */
888     ajint rcnt = 0;             /* Residue count */
889     ajint acnt = 0;             /* Atom count */
890     char id1 = '\0';            /* Residue 1 char id code */
891     AjPStr id3 = NULL;          /* Residue 3 char id code */
892 
893 
894     /* Allocate strings */
895     line = ajStrNew();
896     id3 = ajStrNew();
897 
898     /* Start of main loop */
899     while ((ajReadlineTrim(inf, &line)))
900     {
901         /* Parse NR line */
902         if (ajStrPrefixC(line, "NR"))
903         {
904             ajFmtScanS(line, "%*s %d", &nres);
905 
906             /* Allocate Vdwall object */
907             vdwall = ajVdwallNew(nres);
908 
909         }
910         /* Parse residue id 3 char */
911         else if (ajStrPrefixC(line, "AA"))
912         {
913             rcnt++;
914             acnt = 0;
915             ajFmtScanS(line, "%*s %S", &id3);
916         }
917         /* Parse residue id 1 char */
918         else if (ajStrPrefixC(line, "ID"))
919             ajFmtScanS(line, "%*s %c", &id1);
920         /* Parse number of atoms */
921         else if (ajStrPrefixC(line, "NN"))
922         {
923             ajFmtScanS(line, "%*s %d", &natm);
924 
925             /* Allocate next Vdwres object */
926             vdwall->Res[rcnt - 1] = ajVdwresNew(natm);
927 
928             /* Write members of Vdwres object */
929             vdwall->Res[rcnt - 1]->Id1 = id1;
930             ajStrAssignS(&vdwall->Res[rcnt - 1]->Id3, id3);
931 
932         }
933         /* Parse atom line */
934         else if (ajStrPrefixC(line, "AT"))
935         {
936             acnt++;
937             ajFmtScanS(line, "%*s %S %*c %f",
938                        &vdwall->Res[rcnt - 1]->Atm[acnt - 1],
939                        &vdwall->Res[rcnt - 1]->Rad[acnt - 1]);
940         }
941     }
942 
943     ajStrDel(&line);
944     ajStrDel(&id3);
945 
946     return vdwall;
947 }
948 
949 
950 
951 
952 /* @func ajHetReadNew *********************************************************
953 **
954 ** Read heterogen dictionary, the Het object is allocated.
955 **
956 ** @param [u] inf [AjPFile]    Pointer to Het file
957 **
958 ** @return [AjPHet] Het object.
959 ** @category new [AjPHet] Het constructor from reading dictionary of
960 **                         heterogen groups in clean format (see documentation
961 **                         for the EMBASSY DOMAINATRIX package).
962 **
963 ** @release 2.9.0
964 ** @@
965 ******************************************************************************/
966 
ajHetReadNew(AjPFile inf)967 AjPHet ajHetReadNew(AjPFile inf)
968 {
969     AjPHet het = NULL;
970     AjPHetent hetent = NULL;    /* current entry */
971     AjPList list = NULL;        /* AJAX List of AJAX Heterogen Entry objects */
972     AjPStr line = NULL;         /* current line */
973     AjPStr temp = NULL;         /* Temporary string */
974 
975     /* Check args */
976     if (!inf)
977     {
978         ajWarn("Bad args passed to ajHetReadNew\n");
979 
980         return NULL;
981     }
982 
983     /* Create Het object if necessary */
984     if (!het)
985         het = ajHetNew(0);
986 
987     /* Create string and list objects */
988 
989     line = ajStrNew();
990     temp = ajStrNew();
991     list = ajListNew();
992 
993     /* Read lines from file */
994     while (ajReadlineTrim(inf, &line))
995     {
996         if (ajStrPrefixC(line, "ID   "))
997         {
998             hetent = ajHetentNew();
999             ajFmtScanS(line, "%*s %S", &hetent->abv);
1000         }
1001         else if (ajStrPrefixC(line, "DE   "))
1002         {                       /* NEED TO ACCOUNT FOR MULTIPLE LINES */
1003             ajStrAssignSubS(&temp, line, 5, -1);
1004             if (ajStrGetLen(hetent->ful))
1005                 ajStrAppendS(&hetent->ful, temp);
1006             else
1007                 ajStrAssignS(&hetent->ful, temp);
1008         }
1009         else if (ajStrPrefixC(line, "SY   "))
1010         {
1011 #if AJFALSE
1012             ajFmtScanS(line, "%*s %S", &hetent->syn);
1013 #endif
1014             ajStrAssignSubS(&temp, line, 5, -1);
1015             if (ajStrGetLen(hetent->syn))
1016                 ajStrAppendS(&hetent->syn, temp);
1017             else
1018                 ajStrAssignS(&hetent->syn, temp);
1019         }
1020         else if (ajStrPrefixC(line, "NN   "))
1021             ajFmtScanS(line, "%*s %S", &hetent->cnt);
1022         else if (ajStrPrefixC(line, "//"))
1023             ajListPush(list, (AjPHetent) hetent);
1024     }
1025 
1026     het->Number = (ajuint) ajListToarray(list, (void ***) &het->Entries);
1027 
1028     ajStrDel(&line);
1029     ajStrDel(&temp);
1030 
1031     ajListFree(&list);
1032 
1033     return het;
1034 }
1035 
1036 
1037 
1038 
1039 /* @func ajHetReadRawNew ******************************************************
1040 **
1041 ** Reads a dictionary of heterogen groups available at
1042 ** http://pdb.rutgers.edu/het_dictionary.txt and writes a Het object.
1043 **
1044 ** @param [u] inf [AjPFile]    Pointer to dictionary
1045 **
1046 ** @return [AjPHet] True on success
1047 ** @category new [AjPHet] Het constructor from reading dictionary of
1048 **                        heterogen groups in raw format.
1049 **
1050 ** @release 2.9.0
1051 ** @@
1052 ******************************************************************************/
1053 
ajHetReadRawNew(AjPFile inf)1054 AjPHet ajHetReadRawNew(AjPFile inf)
1055 {
1056     AjPHet het = NULL;
1057     AjPStr line = NULL;         /* A line from the file */
1058     AjPHetent entry = NULL;     /* The current entry */
1059     AjPHetent tmp = NULL;       /* Temp. pointer */
1060     AjPList list = NULL;        /* List of entries */
1061     ajint het_cnt = 0;          /* Count of number of HET records in file */
1062     ajint formul_cnt = 0;       /* Count of number of FORMUL records in file */
1063 
1064     /* Check arg's */
1065     if (!inf)
1066     {
1067         ajWarn("Bad args passed to ajHetReadRawNew\n");
1068         return NULL;
1069     }
1070 
1071     /* Create strings etc */
1072     line = ajStrNew();
1073     list = ajListNew();
1074 
1075     /* Read lines from file */
1076     while (ajReadlineTrim(inf, &line))
1077     {
1078         if (ajStrPrefixC(line, "HET "))
1079         {
1080             het_cnt++;
1081 
1082             entry = ajHetentNew();
1083             ajFmtScanS(line, "%*s %S", &entry->abv);
1084         }
1085         else if (ajStrPrefixC(line, "HETNAM"))
1086         {
1087             ajStrAppendC(&entry->ful, &line->Ptr[15]);
1088         }
1089         else if (ajStrPrefixC(line, "HETSYN"))
1090         {
1091             ajStrAppendC(&entry->syn, &line->Ptr[15]);
1092         }
1093         else if (ajStrPrefixC(line, "FORMUL"))
1094         {
1095             formul_cnt++;
1096 
1097             /* In cases where HETSYN or FORMUL were not specified, assign a
1098              * value of '.' */
1099             if (MAJSTRGETLEN(entry->ful) == 0)
1100                 ajStrAssignC(&entry->ful, ".");
1101 
1102             if (MAJSTRGETLEN(entry->syn) == 0)
1103                 ajStrAssignC(&entry->syn, ".");
1104 
1105 
1106             /* Push entry onto list */
1107             ajListPush(list, (AjPHetent) entry);
1108         }
1109     }
1110 
1111     if (het_cnt != formul_cnt)
1112     {
1113         while (ajListPop(list, (void **) &tmp))
1114             ajHetentDel(&tmp);
1115 
1116         ajListFree(&list);
1117         ajStrDel(&line);
1118 
1119         ajFatal("Fatal discrepancy in count of HET and FORMUL records\n");
1120     }
1121 
1122     het = ajHetNew(0);
1123     het->Number = (ajuint) ajListToarray(list, (void ***) &het->Entries);
1124 
1125     ajStrDel(&line);
1126 
1127     ajListFree(&list);
1128 
1129     return het;
1130 }
1131 
1132 
1133 
1134 
1135 /* @func ajPdbReadFirstModelNew ***********************************************
1136 **
1137 ** Reads a clean coordinate file file (see documentation for DOMAINATRIX
1138 ** "pdbparse" application) and writes a filled Pdb object. Data for the first
1139 ** model only is read in.
1140 **
1141 ** @param [u] inf  [AjPFile] Pointer to clean coordinate file
1142 **
1143 ** @return [AjPPdb] Pointer to Pdb object.
1144 ** @category new [AjPPdb] Pdb constructor from reading ccf format file
1145 **                         (retrieve data for 1st model only).
1146 **
1147 ** @release 2.9.0
1148 ** @@
1149 ******************************************************************************/
1150 
ajPdbReadFirstModelNew(AjPFile inf)1151 AjPPdb ajPdbReadFirstModelNew(AjPFile inf)
1152 {
1153     return (AjPPdb) ajPdbReadNew(inf, 0);
1154 }
1155 
1156 
1157 
1158 
1159 /* @func ajPdbReadAllModelsNew ************************************************
1160 **
1161 ** Reads a clean coordinate file (see documentation for DOMAINATRIX "pdbparse"
1162 ** application) and writes a filled Pdb object.  Data for all models is read.
1163 **
1164 ** @param [u] inf  [AjPFile] Pointer to clean coordinate file
1165 **
1166 ** @return [AjPPdb] Pointer to Pdb object.
1167 ** @category new [AjPPdb] Pdb constructor from reading ccf format file.
1168 **
1169 ** @release 3.0.0
1170 ** @@
1171 ******************************************************************************/
1172 
ajPdbReadAllModelsNew(AjPFile inf)1173 AjPPdb ajPdbReadAllModelsNew(AjPFile inf)
1174 {
1175     return (AjPPdb) ajPdbReadNew(inf, 1);
1176 }
1177 
1178 
1179 
1180 
1181 /* @func ajPdbReadNew *********************************************************
1182 **
1183 ** Reads a clean coordinate file file (see documentation for DOMAINATRIX
1184 ** "pdbparse" application) and writes a filled Pdb object. Data for the first
1185 ** model only is read in.
1186 **
1187 ** @param [u] inf  [AjPFile] Pointer to clean coordinate file
1188 ** @param [r] mode [ajint] Mode. 0==Read first model only. 1==Read all models.
1189 **
1190 ** @return [AjPPdb] Pointer to Pdb object.
1191 ** @category new [AjPPdb] Pdb constructor from reading ccf format file
1192 **                         (retrieve data for 1st model only).
1193 **
1194 ** @release 2.9.0
1195 ** @@
1196 ******************************************************************************/
1197 
ajPdbReadNew(AjPFile inf,ajint mode)1198 AjPPdb ajPdbReadNew(AjPFile inf, ajint mode)
1199 {
1200     AjPPdb pdb = NULL;
1201 
1202     ajint nmod = 0;
1203     ajint ncha = 0;
1204     ajint ngrp = 0;
1205     ajint nc = 0;
1206     ajint mod = 0;
1207     ajint chn = 0;
1208     ajint gpn = 0;
1209 
1210     float reso = 0.0F;
1211 
1212     AjPStr line = NULL;
1213     AjPStr token = NULL;
1214     AjPStr idstr = NULL;
1215     AjPStr destr = NULL;
1216     AjPStr osstr = NULL;
1217     AjPStr xstr = NULL;
1218     AjPStrTok handle = NULL;
1219 
1220     AjPAtom atom = NULL;
1221     AjPResidue residue = NULL;
1222     ajuint rn_last = UINT_MAX;
1223     ajuint mn_last = UINT_MAX;
1224 
1225     AjBool fixReadAtoms = ajTrue;
1226 
1227     /* Initialise strings */
1228     line = ajStrNew();
1229     token = ajStrNew();
1230     idstr = ajStrNew();
1231     destr = ajStrNew();
1232     osstr = ajStrNew();
1233     xstr = ajStrNew();
1234 
1235     /* Start of main loop */
1236     while (ajReadlineTrim(inf, &line))
1237     {
1238         if (ajStrPrefixC(line, "XX"))
1239             continue;
1240 
1241         /* Parse ID */
1242         else if (ajStrPrefixC(line, "ID"))
1243         {
1244             ajStrTokenAssignC(&handle, line, " \n\t\r");
1245             ajStrTokenNextParse(handle, &token);
1246             ajStrTokenNextParse(handle, &idstr);
1247             continue;
1248         }
1249 
1250         /* Parse number of chains */
1251         else if (ajStrPrefixC(line, "CN"))
1252         {
1253             ajStrTokenAssignC(&handle, line, " []\n\t\r");
1254             ajStrTokenNextParse(handle, &token);
1255             ajStrTokenNextParse(handle, &token);
1256             ajStrToInt(token, &nc);
1257             continue;
1258         }
1259 
1260         /* Parse description text */
1261         else if (ajStrPrefixC(line, "DE"))
1262         {
1263             ajStrTokenAssignC(&handle, line, " ");
1264             ajStrTokenNextParse(handle, &token);
1265             /* 'DE' */
1266             ajStrTokenNextParseC(handle, "\n\r", &token);
1267 
1268             /* desc */
1269             if (ajStrGetLen(destr))
1270             {
1271                 ajStrAppendC(&destr, " ");
1272                 ajStrAppendS(&destr, token);
1273             }
1274             else
1275                 ajStrAssignS(&destr, token);
1276             continue;
1277         }
1278 
1279         /* Parse source text */
1280         else if (ajStrPrefixC(line, "OS"))
1281         {
1282             ajStrTokenAssignC(&handle, line, " ");
1283             ajStrTokenNextParse(handle, &token);
1284             /* 'OS' */
1285             ajStrTokenNextParseC(handle, "\n\r", &token);
1286 
1287             /* source */
1288             if (ajStrGetLen(osstr))
1289             {
1290                 ajStrAppendC(&osstr, " ");
1291                 ajStrAppendS(&osstr, token);
1292             }
1293             else
1294                 ajStrAssignS(&osstr, token);
1295             continue;
1296         }
1297 
1298         /* Parse experimental line */
1299         else if (ajStrPrefixC(line, "EX"))
1300         {
1301             ajStrTokenAssignC(&handle, line, " ;\n\t\r");
1302             ajStrTokenNextParse(handle, &token);
1303             ajStrTokenNextParse(handle, &token);
1304 
1305             ajStrTokenNextParse(handle, &xstr);        /* method */
1306             ajStrTokenNextParse(handle, &token);
1307 
1308             ajStrTokenNextParse(handle, &token);       /* reso */
1309             ajStrToFloat(token, &reso);
1310             ajStrTokenNextParse(handle, &token);
1311             ajStrTokenNextParse(handle, &token);       /* nmod */
1312             ajStrToInt(token, &nmod);
1313             ajStrTokenNextParse(handle, &token);
1314 
1315             ajStrTokenNextParse(handle, &token);       /* ncha */
1316             ajStrToInt(token, &ncha);
1317 
1318             ajStrTokenNextParse(handle, &token);       /* nlig */
1319             ajStrToInt(token, &ngrp);
1320 
1321             pdb = ajPdbNew(ncha);
1322 
1323             ajStrAssignS(&pdb->Pdb, idstr);
1324             ajStrAssignS(&pdb->Compnd, destr);
1325             ajStrAssignS(&pdb->Source, osstr);
1326 
1327             if (ajStrMatchC(xstr, "xray"))
1328                 pdb->Method = ajEPdbMethodXray;
1329             else
1330                 pdb->Method = ajEPdbMethodNmr;
1331 
1332             pdb->Reso = reso;
1333 
1334             /*
1335             ** 0 == Read first model only. Number of models is hard-coded to 1
1336             ** as only the data for the first model is read in.
1337             ** 1 == Read all models.
1338             */
1339 
1340             if (mode == 0)
1341                 pdb->Nmod = 1;
1342             else if (mode == 1)
1343                 pdb->Nmod = nmod;
1344             else
1345                 ajFatal("Unrecognised mode in ajPdbReadNew");
1346 
1347             pdb->Nchn = ncha;
1348             pdb->Ngp = ngrp;
1349 
1350             continue;
1351         }
1352 
1353         /* Parse information line */
1354         else if (ajStrPrefixC(line, "IN"))
1355         {
1356             ajStrTokenAssignC(&handle, line, " ;\n\t\r");
1357             ajStrTokenNextParse(handle, &token);
1358             ajStrTokenNextParse(handle, &token);
1359 
1360             /* id value */
1361             ajStrTokenNextParse(handle, &token);
1362             pdb->Chains[nc - 1]->Id = *ajStrGetPtr(token);
1363             ajStrTokenNextParse(handle, &token);
1364 
1365             /* residues */
1366             ajStrTokenNextParse(handle, &token);
1367             ajStrToUint(token, &pdb->Chains[nc - 1]->Nres);
1368             ajStrTokenNextParse(handle, &token);
1369 
1370             /* hetatm */
1371             ajStrTokenNextParse(handle, &token);
1372             ajStrToUint(token, &pdb->Chains[nc - 1]->Nlig);
1373 
1374             /* helices */
1375             ajStrTokenNextParse(handle, &token);
1376             ajStrToInt(token, &pdb->Chains[nc - 1]->numHelices);
1377 
1378             /* strands */
1379             ajStrTokenNextParse(handle, &token);
1380             ajStrToInt(token, &pdb->Chains[nc - 1]->numStrands);
1381 
1382             /* sheets */
1383 #if AJFALSE
1384             ajStrTokenNextParse(handle, &token);
1385             ajStrToInt(token, &pdb->Chains[nc - 1]->numSheets);
1386 #endif
1387             /* turns */
1388 #if AJFALSE
1389             ajStrTokenNextParse(handle, &token);
1390             ajStrToInt(token, &pdb->Chains[nc - 1]->numTurns);
1391 #endif
1392             continue;
1393         }
1394 
1395         /* Parse sequence line */
1396         else if (ajStrPrefixC(line, "SQ"))
1397         {
1398             while (ajReadlineTrim(inf, &line) && !ajStrPrefixC(line, "XX"))
1399                 ajStrAppendC(&pdb->Chains[nc - 1]->Seq, ajStrGetPtr(line));
1400 
1401             ajStrRemoveWhite(&pdb->Chains[nc - 1]->Seq);
1402             continue;
1403         }
1404 
1405         /* Parse atom line */
1406         else if (fixReadAtoms && ajStrPrefixC(line, "AT"))
1407         {
1408             mod = chn = gpn = 0;
1409 
1410             /* Skip AT record */
1411             ajStrTokenAssignC(&handle, line, " \t\n\r");
1412             ajStrTokenNextParse(handle, &token);
1413 
1414             /* Model number. 0 == Read first model only */
1415             ajStrTokenNextParse(handle, &token);
1416             ajStrToInt(token, &mod);
1417 
1418             if ((mode == 0) && (mod != 1))
1419             {
1420                 /* break; */
1421                 /* Discard remaining AT lines */
1422                 while (ajReadlineTrim(inf, &line) && ajStrPrefixC(line, "AT"));
1423             }
1424 
1425             /* Chain number */
1426             ajStrTokenNextParse(handle, &token);
1427             ajStrToInt(token, &chn);
1428 
1429             /* Group number */
1430             ajStrTokenNextParse(handle, &token);
1431             ajStrToInt(token, &gpn);
1432 
1433             /* Allocate object */
1434             atom = ajAtomNew();
1435 
1436             atom->Mod = mod;
1437             atom->Chn = chn;
1438             atom->Gpn = gpn;
1439 
1440             /* Residue number */
1441             ajStrTokenNextParse(handle, &token);
1442             ajStrToUint(token, &atom->Idx);
1443 
1444             /* Residue number string */
1445             ajStrTokenNextParse(handle, &token);
1446             ajStrAssignS(&atom->Pdb, token);
1447 
1448             /* Residue id, 1 char */
1449             ajStrTokenNextParse(handle, &token);
1450             atom->Id1 = *ajStrGetPtr(token);
1451 
1452             /* Residue id, 3 char */
1453             ajStrTokenNextParse(handle, &token);
1454             ajStrAssignS(&atom->Id3, token);
1455 
1456             /* Atom type */
1457             ajStrTokenNextParse(handle, &token);
1458             atom->Type = *ajStrGetPtr(token);
1459 
1460             /* Atom identifier */
1461             ajStrTokenNextParse(handle, &token);
1462             ajStrAssignS(&atom->Atm, token);
1463 
1464             /* X coordinate */
1465             ajStrTokenNextParse(handle, &token);
1466             ajStrToFloat(token, &atom->X);
1467 
1468             /* Y coordinate */
1469             ajStrTokenNextParse(handle, &token);
1470             ajStrToFloat(token, &atom->Y);
1471 
1472             /* Z coordinate */
1473             ajStrTokenNextParse(handle, &token);
1474             ajStrToFloat(token, &atom->Z);
1475 
1476             /* Occupancy */
1477             ajStrTokenNextParse(handle, &token);
1478             ajStrToFloat(token, &atom->O);
1479 
1480             /* B value thermal factor.  */
1481             ajStrTokenNextParse(handle, &token);
1482             ajStrToFloat(token, &atom->B);
1483 
1484             /*
1485             ** Push atom onto appropriate list.
1486             ** Check for coordinates for water or groups that could not
1487             ** be uniquely assigned to a chain
1488             */
1489             if (chn == 0)
1490             {
1491                 /* Heterogen */
1492                 if (atom->Type == 'H')
1493                     ajListPushAppend(pdb->Groups, (void *) atom);
1494                 else if (atom->Type == 'W')
1495                     ajListPushAppend(pdb->Water, (void *) atom);
1496                 else
1497                     ajFatal("Unexpected parse error in "
1498                             "ajPdbReadFirstModelNew");
1499             }
1500             else
1501             {
1502                 ajListPushAppend(pdb->Chains[chn - 1]->Atoms, (void *) atom);
1503             }
1504             continue;
1505         }
1506 
1507         /* Parse residue line */
1508         else if (ajStrPrefixC(line, "RE"))
1509         {
1510             mod = chn = 0;
1511 
1512             /* Skip RE record */
1513             ajStrTokenAssignC(&handle, line, " \t\n\r");
1514             ajStrTokenNextParse(handle, &token);
1515 
1516             /* Model number. 0 == Read first model only */
1517             ajStrTokenNextParse(handle, &token);
1518             ajStrToInt(token, &mod);
1519 
1520             if ((mode == 0) && (mod != 1))
1521             {
1522                 /* break; */
1523                 /* Discard remaining RE lines */
1524                 while (ajReadlineTrim(inf, &line) && ajStrPrefixC(line, "RE"));
1525             }
1526 
1527             /* Chain number */
1528             ajStrTokenNextParse(handle, &token);
1529             ajStrToInt(token, &chn);
1530 
1531             /* Allocate object */
1532             residue = ajResidueNew();
1533 
1534             residue->Mod = mod;
1535             residue->Chn = chn;
1536 
1537             /* Residue number */
1538             ajStrTokenNextParse(handle, &token);
1539             ajStrToUint(token, &residue->Idx);
1540 
1541             /* Residue number (original string) */
1542             ajStrTokenNextParse(handle, &token);
1543             ajStrAssignS(&residue->Pdb, token);
1544 
1545             /* Residue id, 1 char */
1546             ajStrTokenNextParse(handle, &token);
1547             residue->Id1 = *ajStrGetPtr(token);
1548 
1549             /* Residue id, 3 char */
1550             ajStrTokenNextParse(handle, &token);
1551             ajStrAssignS(&residue->Id3, token);
1552 
1553             /* Element serial number (PDB elements) */
1554             ajStrTokenNextParse(handle, &token);
1555             ajStrToInt(token, &residue->eNum);
1556 
1557             /* Element identifier  (PDB elements) */
1558             ajStrTokenNextParse(handle, &token);
1559             ajStrAssignS(&residue->eId, token);
1560 
1561             /* Element type (PDB elements) */
1562             ajStrTokenNextParse(handle, &token);
1563             residue->eType = *ajStrGetPtr(token);
1564 
1565             /* Class of helix  (PDB elements) */
1566             ajStrTokenNextParse(handle, &token);
1567             ajStrToInt(token, &residue->eClass);
1568 
1569             /* Number of the element (stride) */
1570             ajStrTokenNextParse(handle, &token);
1571             ajStrToInt(token, &residue->eStrideNum);
1572 
1573             /* Element type (stride) */
1574             ajStrTokenNextParse(handle, &token);
1575             residue->eStrideType = *ajStrGetPtr(token);
1576 
1577             /* Phi angle */
1578             ajStrTokenNextParse(handle, &token);
1579             ajStrToFloat(token, &residue->Phi);
1580 
1581             /* Psi angle */
1582             ajStrTokenNextParse(handle, &token);
1583             ajStrToFloat(token, &residue->Psi);
1584 
1585             /* Residue solvent accessible area.  */
1586             ajStrTokenNextParse(handle, &token);
1587             ajStrToFloat(token, &residue->Area);
1588 
1589             /* Absolute accessibility, all atoms.  */
1590             ajStrTokenNextParse(handle, &token);
1591             ajStrToFloat(token, &residue->all_abs);
1592 
1593             /* Relative accessibility, all atoms. */
1594             ajStrTokenNextParse(handle, &token);
1595             ajStrToFloat(token, &residue->all_rel);
1596 
1597             /* Absolute accessibility, atoms in side chain.  */
1598             ajStrTokenNextParse(handle, &token);
1599             ajStrToFloat(token, &residue->side_abs);
1600 
1601             /* Relative accessibility, atoms in side chain.  */
1602             ajStrTokenNextParse(handle, &token);
1603             ajStrToFloat(token, &residue->side_rel);
1604 
1605             /* Absolute accessibility, atoms in main chain. */
1606             ajStrTokenNextParse(handle, &token);
1607             ajStrToFloat(token, &residue->main_abs);
1608 
1609             /* Relative accessibility, atoms in main chain. */
1610             ajStrTokenNextParse(handle, &token);
1611             ajStrToFloat(token, &residue->main_rel);
1612 
1613             /* Absolute accessibility, non-polar atoms. */
1614             ajStrTokenNextParse(handle, &token);
1615             ajStrToFloat(token, &residue->npol_abs);
1616 
1617             /* Relative accessibility, non-polar atoms. */
1618             ajStrTokenNextParse(handle, &token);
1619             ajStrToFloat(token, &residue->npol_rel);
1620 
1621             /* Absolute accessibility, polar atoms. */
1622             ajStrTokenNextParse(handle, &token);
1623             ajStrToFloat(token, &residue->pol_abs);
1624 
1625             /* Relative accessibility, polar atoms. */
1626             ajStrTokenNextParse(handle, &token);
1627             ajStrToFloat(token, &residue->pol_rel);
1628 
1629             ajListPushAppend(pdb->Chains[chn - 1]->Residues, (void *) residue);
1630 
1631             continue;
1632         }
1633 
1634         /* Parse coordinate line */
1635         else if (ajStrPrefixC(line, "CO"))
1636         {
1637             mod = chn = gpn = 0;
1638 
1639             ajStrTokenAssignC(&handle, line, " \t\n\r");
1640             ajStrTokenNextParse(handle, &token);
1641 
1642             ajStrTokenNextParse(handle, &token);
1643             ajStrToInt(token, &mod);
1644 
1645             ajStrTokenNextParse(handle, &token);
1646             ajStrToInt(token, &chn);
1647 
1648             ajStrTokenNextParse(handle, &token);
1649             ajStrToInt(token, &gpn);
1650 
1651             atom = ajAtomNew();
1652 
1653             atom->Mod = mod;
1654             atom->Chn = chn;
1655             atom->Gpn = gpn;
1656 
1657             ajStrTokenNextParse(handle, &token);
1658             atom->Type = ajStrGetCharFirst(token);
1659 
1660             ajStrTokenNextParse(handle, &token);
1661             ajStrToUint(token, &atom->Idx);
1662 
1663             ajStrTokenNextParse(handle, &token);
1664             ajStrAssignS(&atom->Pdb, token);
1665 
1666             /* Residue object */
1667             if (atom->Type == 'P')
1668             {
1669                 /* New model */
1670                 if (atom->Mod != mn_last)
1671                 {
1672                     rn_last = UINT_MAX;
1673                     mn_last = atom->Mod;
1674                 }
1675                 /* New residue */
1676                 if (atom->Idx != rn_last)
1677                 {
1678                     residue = ajResidueNew();
1679 
1680                     residue->Mod = atom->Mod;
1681                     residue->Chn = atom->Chn;
1682                     residue->Idx = atom->Idx;
1683                     ajStrAssignS(&residue->Pdb, atom->Pdb);
1684                 }
1685             }
1686 
1687             ajStrTokenNextParse(handle, &token);
1688             residue->eType = *ajStrGetPtr(token);
1689 
1690             ajStrTokenNextParse(handle, &token);
1691             ajStrToInt(token, &residue->eNum);
1692 
1693             ajStrTokenNextParse(handle, &token);
1694             ajStrAssignS(&residue->eId, token);
1695 
1696             ajStrTokenNextParse(handle, &token);
1697             ajStrToInt(token, &residue->eClass);
1698 
1699             ajStrTokenNextParse(handle, &token);
1700             residue->eStrideType = *ajStrGetPtr(token);
1701 
1702             ajStrTokenNextParse(handle, &token);
1703             ajStrToInt(token, &residue->eStrideNum);
1704 
1705             ajStrTokenNextParse(handle, &token);
1706             atom->Id1 = *ajStrGetPtr(token);
1707             residue->Id1 = atom->Id1;
1708 
1709             ajStrTokenNextParse(handle, &token);
1710             ajStrAssignS(&atom->Id3, token);
1711             ajStrAssignS(&residue->Id3, atom->Id3);
1712 
1713             ajStrTokenNextParse(handle, &token);
1714             ajStrAssignS(&atom->Atm, token);
1715 
1716             ajStrTokenNextParse(handle, &token);
1717             ajStrToFloat(token, &atom->X);
1718 
1719             ajStrTokenNextParse(handle, &token);
1720             ajStrToFloat(token, &atom->Y);
1721 
1722             ajStrTokenNextParse(handle, &token);
1723             ajStrToFloat(token, &atom->Z);
1724 
1725             ajStrTokenNextParse(handle, &token);
1726             ajStrToFloat(token, &atom->O);
1727 
1728             ajStrTokenNextParse(handle, &token);
1729             ajStrToFloat(token, &atom->B);
1730 
1731             ajStrTokenNextParse(handle, &token);
1732             ajStrToFloat(token, &residue->Phi);
1733 
1734             ajStrTokenNextParse(handle, &token);
1735             ajStrToFloat(token, &residue->Psi);
1736 
1737             ajStrTokenNextParse(handle, &token);
1738             ajStrToFloat(token, &residue->Area);
1739 
1740             ajStrTokenNextParse(handle, &token);
1741             ajStrToFloat(token, &residue->all_abs);
1742 
1743             ajStrTokenNextParse(handle, &token);
1744             ajStrToFloat(token, &residue->all_rel);
1745 
1746             ajStrTokenNextParse(handle, &token);
1747             ajStrToFloat(token, &residue->side_abs);
1748 
1749             ajStrTokenNextParse(handle, &token);
1750             ajStrToFloat(token, &residue->side_rel);
1751 
1752             ajStrTokenNextParse(handle, &token);
1753             ajStrToFloat(token, &residue->main_abs);
1754 
1755             ajStrTokenNextParse(handle, &token);
1756             ajStrToFloat(token, &residue->main_rel);
1757 
1758             ajStrTokenNextParse(handle, &token);
1759             ajStrToFloat(token, &residue->npol_abs);
1760 
1761             ajStrTokenNextParse(handle, &token);
1762             ajStrToFloat(token, &residue->npol_rel);
1763 
1764             ajStrTokenNextParse(handle, &token);
1765             ajStrToFloat(token, &residue->pol_abs);
1766 
1767             ajStrTokenNextParse(handle, &token);
1768             ajStrToFloat(token, &residue->pol_rel);
1769 
1770 
1771             /* Check for coordinates for water or groups that could not be
1772              * uniquely assigned to a chain */
1773             if (chn == 0)
1774             {
1775                 /* Heterogen */
1776                 if (atom->Type == 'H')
1777                     ajListPushAppend(pdb->Groups, (void *) atom);
1778                 else if (atom->Type == 'W')
1779                     ajListPushAppend(pdb->Water, (void *) atom);
1780                 else
1781                     ajFatal("Unexpected parse error in ajPdbRead");
1782             }
1783             else
1784                 ajListPushAppend(pdb->Chains[chn - 1]->Atoms, (void *) atom);
1785 
1786             ajListPushAppend(pdb->Chains[chn - 1]->Residues, (void *) residue);
1787         }
1788     }
1789     /* End of main application loop */
1790 
1791     ajStrTokenDel(&handle);
1792     ajStrDel(&line);
1793     ajStrDel(&token);
1794     ajStrDel(&idstr);
1795     ajStrDel(&destr);
1796     ajStrDel(&osstr);
1797     ajStrDel(&xstr);
1798 
1799     return pdb;
1800 }
1801 
1802 
1803 
1804 
1805 /* @func ajPdbReadoldNew ******************************************************
1806 **
1807 ** Reads a clean coordinate file (see documentation for DOMAINATRIX "pdbparse"
1808 ** application) lacking residue-level description in RE records and writes a
1809 ** filled Pdb object.
1810 **
1811 ** @param [u] inf  [AjPFile] Pointer to clean coordinate file
1812 **
1813 ** @return [AjPPdb] Pointer to Pdb object.
1814 ** @category new [AjPPdb] Pdb constructor from reading ccf format file.
1815 **
1816 ** @release 3.0.0
1817 ** @@
1818 ******************************************************************************/
1819 
ajPdbReadoldNew(AjPFile inf)1820 AjPPdb ajPdbReadoldNew(AjPFile inf)
1821 {
1822     AjPPdb pdb = NULL;
1823 
1824     ajint nmod = 0;
1825     ajint ncha = 0;
1826     ajint ngrp = 0;
1827     ajint nc = 0;
1828     ajint mod = 0;
1829     ajint chn = 0;
1830     ajint gpn = 0;
1831 
1832     float reso = 0.0F;
1833 
1834     AjPStr line = NULL;
1835     AjPStr token = NULL;
1836     AjPStr idstr = NULL;
1837     AjPStr destr = NULL;
1838     AjPStr osstr = NULL;
1839     AjPStr xstr = NULL;
1840     AjPStrTok handle = NULL;
1841 
1842     AjPAtom atom = NULL;
1843     AjPResidue residue = NULL;
1844     ajuint rn_last = UINT_MAX;
1845     ajuint mn_last = UINT_MAX;
1846 
1847 
1848     /* Initialise strings */
1849     line = ajStrNew();
1850     token = ajStrNew();
1851     idstr = ajStrNew();
1852     destr = ajStrNew();
1853     osstr = ajStrNew();
1854     xstr = ajStrNew();
1855 
1856     /* Start of main application loop */
1857     while (ajReadlineTrim(inf, &line))
1858     {
1859         if (ajStrPrefixC(line, "XX"))
1860             continue;
1861 
1862         /* Parse ID */
1863         if (ajStrPrefixC(line, "ID"))
1864         {
1865             ajStrTokenAssignC(&handle, line, " \n\t\r");
1866             ajStrTokenNextParse(handle, &token);
1867             ajStrTokenNextParse(handle, &idstr);
1868             continue;
1869         }
1870 
1871 
1872         /* Parse number of chains */
1873         if (ajStrPrefixC(line, "CN"))
1874         {
1875             ajStrTokenAssignC(&handle, line, " []\n\t\r");
1876             ajStrTokenNextParse(handle, &token);
1877             ajStrTokenNextParse(handle, &token);
1878             ajStrToInt(token, &nc);
1879             continue;
1880         }
1881 
1882 
1883         /* Parse description text */
1884         if (ajStrPrefixC(line, "DE"))
1885         {
1886             ajStrTokenAssignC(&handle, line, " ");
1887             ajStrTokenNextParse(handle, &token);
1888             /* 'DE' */
1889             ajStrTokenNextParseC(handle, "\n\r", &token);
1890 
1891             /* desc */
1892             if (ajStrGetLen(destr))
1893             {
1894                 ajStrAppendC(&destr, " ");
1895                 ajStrAppendS(&destr, token);
1896             }
1897             else
1898                 ajStrAssignS(&destr, token);
1899             continue;
1900         }
1901 
1902 
1903         /* Parse source text */
1904         if (ajStrPrefixC(line, "OS"))
1905         {
1906             ajStrTokenAssignC(&handle, line, " ");
1907             ajStrTokenNextParse(handle, &token);
1908             /* 'OS' */
1909             ajStrTokenNextParseC(handle, "\n\r", &token);
1910 
1911             /* source */
1912             if (ajStrGetLen(osstr))
1913             {
1914                 ajStrAppendC(&osstr, " ");
1915                 ajStrAppendS(&osstr, token);
1916             }
1917             else
1918                 ajStrAssignS(&osstr, token);
1919 
1920             continue;
1921         }
1922 
1923 
1924         /* Parse experimental line */
1925         if (ajStrPrefixC(line, "EX"))
1926         {
1927             ajStrTokenAssignC(&handle, line, " ;\n\t\r");
1928             ajStrTokenNextParse(handle, &token);
1929             ajStrTokenNextParse(handle, &token);
1930 
1931             ajStrTokenNextParse(handle, &xstr);        /* method */
1932             ajStrTokenNextParse(handle, &token);
1933 
1934             ajStrTokenNextParse(handle, &token);       /* reso */
1935             ajStrToFloat(token, &reso);
1936             ajStrTokenNextParse(handle, &token);
1937             ajStrTokenNextParse(handle, &token);       /* nmod */
1938             ajStrToInt(token, &nmod);
1939             ajStrTokenNextParse(handle, &token);
1940 
1941             ajStrTokenNextParse(handle, &token);       /* nchn */
1942             ajStrToInt(token, &ncha);
1943 
1944             ajStrTokenNextParse(handle, &token);       /* nlig */
1945             ajStrToInt(token, &ngrp);
1946 
1947             pdb = ajPdbNew(ncha);
1948 
1949             ajStrAssignS(&pdb->Pdb, idstr);
1950             ajStrAssignS(&pdb->Compnd, destr);
1951             ajStrAssignS(&pdb->Source, osstr);
1952 
1953             if (ajStrMatchC(xstr, "xray"))
1954                 pdb->Method = ajEPdbMethodXray;
1955             else
1956                 pdb->Method = ajEPdbMethodNmr;
1957 
1958             pdb->Reso = reso;
1959             pdb->Nmod = nmod;
1960             pdb->Nchn = ncha;
1961             pdb->Ngp = ngrp;
1962         }
1963 
1964 
1965         /* Parse information line */
1966         if (ajStrPrefixC(line, "IN"))
1967         {
1968             ajStrTokenAssignC(&handle, line, " ;\n\t\r");
1969             ajStrTokenNextParse(handle, &token);
1970             ajStrTokenNextParse(handle, &token);
1971             ajStrTokenNextParse(handle, &token);       /* id value */
1972             pdb->Chains[nc - 1]->Id = *ajStrGetPtr(token);
1973             ajStrTokenNextParse(handle, &token);
1974             ajStrTokenNextParse(handle, &token);       /* residues */
1975             ajStrToUint(token, &pdb->Chains[nc - 1]->Nres);
1976             ajStrTokenNextParse(handle, &token);
1977             /* hetatm */
1978             ajStrTokenNextParse(handle, &token);
1979             ajStrToUint(token, &pdb->Chains[nc - 1]->Nlig);
1980             /* helices */
1981             ajStrTokenNextParse(handle, &token);
1982             ajStrToInt(token, &pdb->Chains[nc - 1]->numHelices);
1983             /* strands */
1984             ajStrTokenNextParse(handle, &token);
1985             ajStrToInt(token, &pdb->Chains[nc - 1]->numStrands);
1986             /* sheets */
1987 #if AJFALSE
1988             ajStrTokenNextParse(handle, &token);
1989             ajStrToInt(token, &pdb->Chains[nc - 1]->numSheets);
1990 #endif
1991             /* turns */
1992 #if AJFALSE
1993             ajStrTokenNextParse(handle, &token);
1994             ajStrToInt(token, &pdb->Chains[nc - 1]->numTurns);
1995 #endif
1996             continue;
1997         }
1998 
1999 
2000         /* Parse sequence line */
2001         if (ajStrPrefixC(line, "SQ"))
2002         {
2003             while (ajReadlineTrim(inf, &line) && !ajStrPrefixC(line, "XX"))
2004                 ajStrAppendC(&pdb->Chains[nc - 1]->Seq, ajStrGetPtr(line));
2005             ajStrRemoveWhite(&pdb->Chains[nc - 1]->Seq);
2006 
2007             continue;
2008         }
2009 
2010 
2011         /* Parse coordinate line */
2012         if (ajStrPrefixC(line, "CO"))
2013         {
2014             mod = chn = gpn = 0;
2015 
2016             ajStrTokenAssignC(&handle, line, " \t\n\r");
2017             ajStrTokenNextParse(handle, &token);
2018 
2019             ajStrTokenNextParse(handle, &token);
2020             ajStrToInt(token, &mod);
2021 
2022             ajStrTokenNextParse(handle, &token);
2023             ajStrToInt(token, &chn);
2024 
2025             ajStrTokenNextParse(handle, &token);
2026             ajStrToInt(token, &gpn);
2027 
2028             atom = ajAtomNew();
2029 
2030             atom->Mod = mod;
2031             atom->Chn = chn;
2032             atom->Gpn = gpn;
2033 
2034             ajStrTokenNextParse(handle, &token);
2035             atom->Type = *ajStrGetPtr(token);
2036 
2037             ajStrTokenNextParse(handle, &token);
2038             ajStrToUint(token, &atom->Idx);
2039 
2040             ajStrTokenNextParse(handle, &token);
2041             ajStrAssignS(&atom->Pdb, token);
2042 
2043 
2044             /* Residue object */
2045             if (atom->Type == 'P')
2046             {
2047                 /* New model */
2048                 if (atom->Mod != mn_last)
2049                 {
2050                     rn_last = UINT_MAX;
2051                     mn_last = atom->Mod;
2052                 }
2053 
2054                 /* New residue */
2055                 if (atom->Idx != rn_last)
2056                 {
2057                     residue = ajResidueNew();
2058 
2059                     residue->Mod = atom->Mod;
2060                     residue->Chn = atom->Chn;
2061                     residue->Idx = atom->Idx;
2062                     ajStrAssignS(&residue->Pdb, atom->Pdb);
2063                 }
2064             }
2065 
2066             ajStrTokenNextParse(handle, &token);
2067             residue->eType = *ajStrGetPtr(token);
2068 
2069             ajStrTokenNextParse(handle, &token);
2070             ajStrToInt(token, &residue->eNum);
2071 
2072             ajStrTokenNextParse(handle, &token);
2073             ajStrAssignS(&residue->eId, token);
2074 
2075             ajStrTokenNextParse(handle, &token);
2076             ajStrToInt(token, &residue->eClass);
2077 
2078             ajStrTokenNextParse(handle, &token);
2079             residue->eStrideType = *ajStrGetPtr(token);
2080 
2081             ajStrTokenNextParse(handle, &token);
2082             ajStrToInt(token, &residue->eStrideNum);
2083 
2084             ajStrTokenNextParse(handle, &token);
2085             atom->Id1 = *ajStrGetPtr(token);
2086             residue->Id1 = atom->Id1;
2087 
2088             ajStrTokenNextParse(handle, &token);
2089             ajStrAssignS(&atom->Id3, token);
2090             ajStrAssignS(&residue->Id3, atom->Id3);
2091 
2092             ajStrTokenNextParse(handle, &token);
2093             ajStrAssignS(&atom->Atm, token);
2094 
2095             ajStrTokenNextParse(handle, &token);
2096             ajStrToFloat(token, &atom->X);
2097 
2098             ajStrTokenNextParse(handle, &token);
2099             ajStrToFloat(token, &atom->Y);
2100 
2101             ajStrTokenNextParse(handle, &token);
2102             ajStrToFloat(token, &atom->Z);
2103 
2104             ajStrTokenNextParse(handle, &token);
2105             ajStrToFloat(token, &atom->O);
2106 
2107             ajStrTokenNextParse(handle, &token);
2108             ajStrToFloat(token, &atom->B);
2109 
2110             ajStrTokenNextParse(handle, &token);
2111             ajStrToFloat(token, &residue->Phi);
2112 
2113             ajStrTokenNextParse(handle, &token);
2114             ajStrToFloat(token, &residue->Psi);
2115 
2116             ajStrTokenNextParse(handle, &token);
2117             ajStrToFloat(token, &residue->Area);
2118 
2119             ajStrTokenNextParse(handle, &token);
2120             ajStrToFloat(token, &residue->all_abs);
2121 
2122             ajStrTokenNextParse(handle, &token);
2123             ajStrToFloat(token, &residue->all_rel);
2124 
2125             ajStrTokenNextParse(handle, &token);
2126             ajStrToFloat(token, &residue->side_abs);
2127 
2128             ajStrTokenNextParse(handle, &token);
2129             ajStrToFloat(token, &residue->side_rel);
2130 
2131             ajStrTokenNextParse(handle, &token);
2132             ajStrToFloat(token, &residue->main_abs);
2133 
2134             ajStrTokenNextParse(handle, &token);
2135             ajStrToFloat(token, &residue->main_rel);
2136 
2137             ajStrTokenNextParse(handle, &token);
2138             ajStrToFloat(token, &residue->npol_abs);
2139 
2140             ajStrTokenNextParse(handle, &token);
2141             ajStrToFloat(token, &residue->npol_rel);
2142 
2143             ajStrTokenNextParse(handle, &token);
2144             ajStrToFloat(token, &residue->pol_abs);
2145 
2146             ajStrTokenNextParse(handle, &token);
2147             ajStrToFloat(token, &residue->pol_rel);
2148 
2149 
2150             /* Check for coordinates for water or groups that could not be
2151              * uniquely assigned to a chain */
2152             if (chn == 0)
2153             {
2154                 /* Heterogen */
2155                 if (atom->Type == 'H')
2156                     ajListPushAppend(pdb->Groups, (void *) atom);
2157                 else if (atom->Type == 'W')
2158                     ajListPushAppend(pdb->Water, (void *) atom);
2159                 else
2160                     ajFatal("Unexpected parse error in ajPdbRead");
2161             }
2162             else
2163                 ajListPushAppend(pdb->Chains[chn - 1]->Atoms, (void *) atom);
2164 
2165 
2166             ajListPushAppend(pdb->Chains[chn - 1]->Residues, (void *) residue);
2167         }
2168     }
2169     /* End of main application loop */
2170 
2171 
2172 
2173     ajStrTokenDel(&handle);
2174     ajStrDel(&line);
2175     ajStrDel(&token);
2176     ajStrDel(&idstr);
2177     ajStrDel(&destr);
2178     ajStrDel(&osstr);
2179     ajStrDel(&xstr);
2180 
2181     return pdb;
2182 }
2183 
2184 
2185 
2186 
2187 /* @func ajPdbReadoldFirstModelNew ********************************************
2188 **
2189 ** Reads a clean coordinate file file (see documentation for DOMAINATRIX
2190 ** "pdbparse" application) lacking residue-level description in RE records and
2191 ** writes a filled Pdb object. Data for the first model only is read in.
2192 **
2193 ** @param [u] inf  [AjPFile] Pointer to clean coordinate file
2194 **
2195 ** @return [AjPPdb] Pointer to Pdb object.
2196 ** @category new [AjPPdb] Pdb constructor from reading ccf format file
2197 **                         (retrieve data for 1st model only).
2198 **
2199 ** @release 3.0.0
2200 ** @@
2201 ******************************************************************************/
2202 
ajPdbReadoldFirstModelNew(AjPFile inf)2203 AjPPdb ajPdbReadoldFirstModelNew(AjPFile inf)
2204 {
2205     AjPPdb ret = NULL;
2206 
2207     ajint nmod = 0;
2208     ajint ncha = 0;
2209     ajint ngrp = 0;
2210     ajint nc = 0;
2211     ajint mod = 0;
2212     ajint chn = 0;
2213     ajint gpn = 0;
2214 
2215     float reso = 0.0F;
2216 
2217     AjPStr line = NULL;
2218     AjPStr token = NULL;
2219     AjPStr idstr = NULL;
2220     AjPStr destr = NULL;
2221     AjPStr osstr = NULL;
2222     AjPStr xstr = NULL;
2223     AjPStrTok handle = NULL;
2224 
2225     AjPAtom atom = NULL;
2226     AjPResidue res = NULL;
2227     ajuint rn_last = UINT_MAX;
2228     ajuint mn_last = UINT_MAX;
2229 
2230     /* Initialise strings */
2231     line = ajStrNew();
2232     token = ajStrNew();
2233     idstr = ajStrNew();
2234     destr = ajStrNew();
2235     osstr = ajStrNew();
2236     xstr = ajStrNew();
2237 
2238     /* Start of main application loop */
2239     while (ajReadlineTrim(inf, &line))
2240     {
2241         if (ajStrPrefixC(line, "XX"))
2242             continue;
2243 
2244         /* Parse ID */
2245         if (ajStrPrefixC(line, "ID"))
2246         {
2247             ajStrTokenAssignC(&handle, line, " \n\t\r");
2248             ajStrTokenNextParse(handle, &token);
2249             ajStrTokenNextParse(handle, &idstr);
2250             continue;
2251         }
2252 
2253 
2254         /* Parse number of chains */
2255         if (ajStrPrefixC(line, "CN"))
2256         {
2257             ajStrTokenAssignC(&handle, line, " []\n\t\r");
2258             ajStrTokenNextParse(handle, &token);
2259             ajStrTokenNextParse(handle, &token);
2260             ajStrToInt(token, &nc);
2261             continue;
2262         }
2263 
2264 
2265         /* Parse description text */
2266         if (ajStrPrefixC(line, "DE"))
2267         {
2268             ajStrTokenAssignC(&handle, line, " ");
2269             ajStrTokenNextParse(handle, &token);
2270             /* 'DE' */
2271             ajStrTokenNextParseC(handle, "\n\r", &token);
2272 
2273             /* desc */
2274             if (ajStrGetLen(destr))
2275             {
2276                 ajStrAppendC(&destr, " ");
2277                 ajStrAppendS(&destr, token);
2278             }
2279             else
2280                 ajStrAssignS(&destr, token);
2281 
2282             continue;
2283         }
2284 
2285 
2286         /* Parse source text */
2287         if (ajStrPrefixC(line, "OS"))
2288         {
2289             ajStrTokenAssignC(&handle, line, " ");
2290             ajStrTokenNextParse(handle, &token);
2291             /* 'OS' */
2292             ajStrTokenNextParseC(handle, "\n\r", &token);
2293 
2294             /* source */
2295             if (ajStrGetLen(osstr))
2296             {
2297                 ajStrAppendC(&osstr, " ");
2298                 ajStrAppendS(&osstr, token);
2299             }
2300             else
2301                 ajStrAssignS(&osstr, token);
2302             continue;
2303         }
2304 
2305 
2306         /* Parse experimental line */
2307         if (ajStrPrefixC(line, "EX"))
2308         {
2309             ajStrTokenAssignC(&handle, line, " ;\n\t\r");
2310             ajStrTokenNextParse(handle, &token);
2311             ajStrTokenNextParse(handle, &token);
2312 
2313             ajStrTokenNextParse(handle, &xstr);        /* method */
2314             ajStrTokenNextParse(handle, &token);
2315 
2316             ajStrTokenNextParse(handle, &token);       /* reso */
2317             ajStrToFloat(token, &reso);
2318             ajStrTokenNextParse(handle, &token);
2319             ajStrTokenNextParse(handle, &token);       /* nmod */
2320             ajStrToInt(token, &nmod);
2321             ajStrTokenNextParse(handle, &token);
2322 
2323             ajStrTokenNextParse(handle, &token);       /* ncha */
2324             ajStrToInt(token, &ncha);
2325 
2326             ajStrTokenNextParse(handle, &token);       /* nlig */
2327             ajStrToInt(token, &ngrp);
2328 
2329             ret = ajPdbNew(ncha);
2330 
2331             ajStrAssignS(&(ret)->Pdb, idstr);
2332             ajStrAssignS(&(ret)->Compnd, destr);
2333             ajStrAssignS(&(ret)->Source, osstr);
2334 
2335             if (ajStrMatchC(xstr, "xray"))
2336                 (ret)->Method = ajEPdbMethodXray;
2337             else
2338                 (ret)->Method = ajEPdbMethodNmr;
2339 
2340             (ret)->Reso = reso;
2341             /* (ret)->Nmod = nmod; */
2342 
2343             /*
2344             ** Number of models is hard-coded to 1 as only the
2345             **  data for the first model is read in
2346             */
2347             (ret)->Nmod = 1;
2348             (ret)->Nchn = ncha;
2349             (ret)->Ngp = ngrp;
2350         }
2351 
2352 
2353         /* Parse information line */
2354         if (ajStrPrefixC(line, "IN"))
2355         {
2356             ajStrTokenAssignC(&handle, line, " ;\n\t\r");
2357             ajStrTokenNextParse(handle, &token);
2358             ajStrTokenNextParse(handle, &token);
2359             ajStrTokenNextParse(handle, &token);       /* id value */
2360             (ret)->Chains[nc - 1]->Id = *ajStrGetPtr(token);
2361             ajStrTokenNextParse(handle, &token);
2362             ajStrTokenNextParse(handle, &token);       /* residues */
2363             ajStrToUint(token, &(ret)->Chains[nc - 1]->Nres);
2364             ajStrTokenNextParse(handle, &token);
2365             /* hetatm */
2366             ajStrTokenNextParse(handle, &token);
2367             ajStrToUint(token, &(ret)->Chains[nc - 1]->Nlig);
2368             /* helices */
2369             ajStrTokenNextParse(handle, &token);
2370             ajStrToInt(token, &(ret)->Chains[nc - 1]->numHelices);
2371             /* strands */
2372             ajStrTokenNextParse(handle, &token);
2373             ajStrToInt(token, &(ret)->Chains[nc - 1]->numStrands);
2374             /* sheets */
2375 #if AJFALSE
2376             ajStrTokenNextParse(handle, &token);
2377             ajStrToInt(token, &(ret)->Chains[nc - 1]->numSheets);
2378 #endif
2379             /* turns */
2380 #if AJFALSE
2381             ajStrTokenNextParse(handle, &token);
2382             ajStrToInt(token, &(ret)->Chains[nc - 1]->numTurns);
2383 #endif
2384 
2385             continue;
2386         }
2387 
2388 
2389         /* Parse sequence line */
2390         if (ajStrPrefixC(line, "SQ"))
2391         {
2392             while (ajReadlineTrim(inf, &line) && !ajStrPrefixC(line, "XX"))
2393                 ajStrAppendC(&(ret)->Chains[nc - 1]->Seq, ajStrGetPtr(line));
2394 
2395             ajStrRemoveWhite(&(ret)->Chains[nc - 1]->Seq);
2396             continue;
2397         }
2398 
2399 
2400         /* Parse coordinate line */
2401         if (ajStrPrefixC(line, "CO"))
2402         {
2403             mod = chn = gpn = 0;
2404 
2405             ajStrTokenAssignC(&handle, line, " \t\n\r");
2406             ajStrTokenNextParse(handle, &token);
2407 
2408             ajStrTokenNextParse(handle, &token);
2409             ajStrToInt(token, &mod);
2410 
2411             if (mod != 1)
2412                 break;
2413 
2414             ajStrTokenNextParse(handle, &token);
2415             ajStrToInt(token, &chn);
2416 
2417             ajStrTokenNextParse(handle, &token);
2418             ajStrToInt(token, &gpn);
2419 
2420             atom = ajAtomNew();
2421 
2422             atom->Mod = mod;
2423             atom->Chn = chn;
2424             atom->Gpn = gpn;
2425 
2426 
2427             ajStrTokenNextParse(handle, &token);
2428             atom->Type = *ajStrGetPtr(token);
2429 
2430             ajStrTokenNextParse(handle, &token);
2431             ajStrToUint(token, &atom->Idx);
2432 
2433             ajStrTokenNextParse(handle, &token);
2434             ajStrAssignS(&atom->Pdb, token);
2435 
2436             /* Residue object */
2437             if (atom->Type == 'P')
2438             {
2439                 /* New model */
2440                 if (atom->Mod != mn_last)
2441                 {
2442                     rn_last = UINT_MAX;
2443                     mn_last = atom->Mod;
2444                 }
2445 
2446                 /* New residue */
2447                 if (atom->Idx != rn_last)
2448                 {
2449                     res = ajResidueNew();
2450 
2451                     res->Mod = atom->Mod;
2452                     res->Chn = atom->Chn;
2453                     res->Idx = atom->Idx;
2454                     ajStrAssignS(&res->Pdb, atom->Pdb);
2455                 }
2456             }
2457 
2458 
2459             ajStrTokenNextParse(handle, &token);
2460             res->eType = *ajStrGetPtr(token);
2461 
2462             ajStrTokenNextParse(handle, &token);
2463             ajStrToInt(token, &res->eNum);
2464 
2465             ajStrTokenNextParse(handle, &token);
2466             ajStrAssignS(&res->eId, token);
2467 
2468             ajStrTokenNextParse(handle, &token);
2469             ajStrToInt(token, &res->eClass);
2470 
2471             ajStrTokenNextParse(handle, &token);
2472             res->eStrideType = *ajStrGetPtr(token);
2473 
2474             ajStrTokenNextParse(handle, &token);
2475             ajStrToInt(token, &res->eStrideNum);
2476 
2477             ajStrTokenNextParse(handle, &token);
2478             atom->Id1 = *ajStrGetPtr(token);
2479 
2480             ajStrTokenNextParse(handle, &token);
2481             ajStrAssignS(&atom->Id3, token);
2482             ajStrAssignS(&res->Id3, atom->Id3);
2483 
2484             ajStrTokenNextParse(handle, &token);
2485             ajStrAssignS(&atom->Atm, token);
2486 
2487             ajStrTokenNextParse(handle, &token);
2488             ajStrToFloat(token, &atom->X);
2489 
2490             ajStrTokenNextParse(handle, &token);
2491             ajStrToFloat(token, &atom->Y);
2492 
2493             ajStrTokenNextParse(handle, &token);
2494             ajStrToFloat(token, &atom->Z);
2495 
2496             ajStrTokenNextParse(handle, &token);
2497             ajStrToFloat(token, &atom->O);
2498 
2499             ajStrTokenNextParse(handle, &token);
2500             ajStrToFloat(token, &atom->B);
2501 
2502             ajStrTokenNextParse(handle, &token);
2503             ajStrToFloat(token, &res->Phi);
2504 
2505             ajStrTokenNextParse(handle, &token);
2506             ajStrToFloat(token, &res->Psi);
2507 
2508             ajStrTokenNextParse(handle, &token);
2509             ajStrToFloat(token, &res->Area);
2510 
2511             ajStrTokenNextParse(handle, &token);
2512             ajStrToFloat(token, &res->all_abs);
2513 
2514             ajStrTokenNextParse(handle, &token);
2515             ajStrToFloat(token, &res->all_rel);
2516 
2517             ajStrTokenNextParse(handle, &token);
2518             ajStrToFloat(token, &res->side_abs);
2519 
2520             ajStrTokenNextParse(handle, &token);
2521             ajStrToFloat(token, &res->side_rel);
2522 
2523             ajStrTokenNextParse(handle, &token);
2524             ajStrToFloat(token, &res->main_abs);
2525 
2526             ajStrTokenNextParse(handle, &token);
2527             ajStrToFloat(token, &res->main_rel);
2528 
2529             ajStrTokenNextParse(handle, &token);
2530             ajStrToFloat(token, &res->npol_abs);
2531 
2532             ajStrTokenNextParse(handle, &token);
2533             ajStrToFloat(token, &res->npol_rel);
2534 
2535             ajStrTokenNextParse(handle, &token);
2536             ajStrToFloat(token, &res->pol_abs);
2537 
2538             ajStrTokenNextParse(handle, &token);
2539             ajStrToFloat(token, &res->pol_rel);
2540 
2541             /* Check for coordinates for water or groups that could not * be
2542              * uniquely assigned to a chain */
2543             if (chn == 0)
2544             {
2545                 /* Heterogen */
2546                 if (atom->Type == 'H')
2547                     ajListPushAppend((ret)->Groups, (void *) atom);
2548                 else if (atom->Type == 'W')
2549                     ajListPushAppend((ret)->Water, (void *) atom);
2550                 else
2551                     ajFatal("Unexpected parse error in "
2552                             "ajPdbReadFirstModelNew");
2553             }
2554             else
2555                 ajListPushAppend((ret)->Chains[chn - 1]->Atoms, (void *) atom);
2556 
2557             ajListPushAppend((ret)->Chains[chn - 1]->Residues, (void *) res);
2558         }
2559     }
2560     /* End of main application loop */
2561 
2562 
2563     ajStrTokenDel(&handle);
2564     ajStrDel(&line);
2565     ajStrDel(&token);
2566     ajStrDel(&idstr);
2567     ajStrDel(&destr);
2568     ajStrDel(&osstr);
2569     ajStrDel(&xstr);
2570 
2571     return ret;
2572 }
2573 
2574 
2575 
2576 
2577 /* @func ajAtomNew ************************************************************
2578 **
2579 ** Atom object constructor.
2580 ** This is normally called by the ajChainNew function.
2581 **
2582 ** @return [AjPAtom] Pointer to an atom object
2583 ** @category new [AjPAtom] Default Atom constructor.
2584 **
2585 ** @release 1.8.0
2586 ** @@
2587 ******************************************************************************/
2588 
ajAtomNew(void)2589 AjPAtom ajAtomNew(void)
2590 {
2591     AjPAtom atom = NULL;
2592 
2593     AJNEW0(atom);
2594 
2595     atom->Id3 = ajStrNew();
2596     atom->Atm = ajStrNew();
2597     atom->Pdb = ajStrNew();
2598 #if AJFALSE
2599     atom->eId = ajStrNew();
2600 #endif
2601     atom->Id1 = '.';
2602 #if AJFALSE
2603     atom->eType = '.';
2604     ajStrAssignC(&atom->eId, ".");
2605     atom->eStrideType = '.';
2606 #endif
2607 
2608     return atom;
2609 }
2610 
2611 
2612 
2613 
2614 /* @func ajResidueNew *********************************************************
2615 **
2616 ** Residue object constructor.
2617 ** This is normally called by the ajChainNew function.
2618 **
2619 ** @return [AjPResidue] Pointer to a Residue object
2620 ** @category new [AjPResidue] Default Residue constructor.
2621 **
2622 ** @release 3.0.0
2623 ** @@
2624 ******************************************************************************/
2625 
ajResidueNew(void)2626 AjPResidue ajResidueNew(void)
2627 {
2628     AjPResidue residue = NULL;
2629 
2630     AJNEW0(residue);
2631 
2632     residue->Pdb = ajStrNew();
2633     residue->Id3 = ajStrNew();
2634     residue->eId = ajStrNew();
2635 
2636     residue->Id1 = '.';
2637     residue->eType = '.';
2638     ajStrAssignC(&residue->eId, ".");
2639     residue->eStrideType = '.';
2640 
2641     return residue;
2642 }
2643 
2644 
2645 
2646 
2647 /* @func ajChainNew ***********************************************************
2648 **
2649 ** Chain object constructor.
2650 ** This is normally called by the ajPdbNew function
2651 **
2652 ** @return [AjPChain] Pointer to a chain object
2653 **
2654 ** @release 1.8.0
2655 ** @@
2656 ** @category new [AjPChain] Default Chain constructor.
2657 ******************************************************************************/
2658 
ajChainNew(void)2659 AjPChain ajChainNew(void)
2660 {
2661     AjPChain chain = NULL;
2662 
2663     AJNEW0(chain);
2664 
2665     chain->Seq = ajStrNewC("");
2666     chain->Atoms = ajListNew();
2667     chain->Residues = ajListNew();
2668 
2669     return chain;
2670 }
2671 
2672 
2673 
2674 
2675 /* @func ajPdbNew *************************************************************
2676 **
2677 ** Pdb object constructor. Fore-knowledge of the number of chains
2678 ** is required. This is normally called by the functions that read PDB
2679 ** files or clean coordinate files (see embpdb.c & embpdbraw.c).
2680 **
2681 ** @param [r] n [ajuint] Number of chains in this pdb file
2682 **
2683 ** @return [AjPPdb] Pointer to a pdb object
2684 ** @category new [AjPPdb] Default Pdb constructor.
2685 **
2686 ** @release 1.8.0
2687 ** @@
2688 ******************************************************************************/
2689 
ajPdbNew(ajuint n)2690 AjPPdb ajPdbNew(ajuint n)
2691 {
2692     ajuint i = 0U;
2693 
2694     AjPPdb pdb = NULL;
2695 
2696     AJNEW0(pdb);
2697 
2698     pdb->Pdb = ajStrNew();
2699     pdb->Compnd = ajStrNew();
2700     pdb->Source = ajStrNew();
2701     pdb->Groups = ajListNew();
2702     pdb->Water = ajListNew();
2703     pdb->gpid = ajChararrNew();
2704 
2705     if (n)
2706     {
2707         AJCNEW0(pdb->Chains, n);
2708 
2709         for (i = 0U; i < n; ++i)
2710             pdb->Chains[i] = ajChainNew();
2711     }
2712 
2713     return pdb;
2714 }
2715 
2716 
2717 
2718 
2719 /* @func ajHetentNew **********************************************************
2720 **
2721 ** Hetent object constructor.
2722 **
2723 ** @return [AjPHetent] Pointer to a Hetent object
2724 ** @category new [AjPHetent] Default Hetent constructor.
2725 **
2726 ** @release 2.9.0
2727 ** @@
2728 ******************************************************************************/
2729 
ajHetentNew(void)2730 AjPHetent ajHetentNew(void)
2731 {
2732     AjPHetent hetent = NULL;
2733 
2734     AJNEW0(hetent);
2735 
2736     hetent->abv = ajStrNew();
2737     hetent->syn = ajStrNew();
2738     hetent->ful = ajStrNew();
2739 
2740     return hetent;
2741 }
2742 
2743 
2744 
2745 
2746 /* @func ajHetNew *************************************************************
2747 **
2748 ** Het object constructor.
2749 **
2750 ** @param [r] n [ajuint] Number of entries in dictionary.
2751 **
2752 ** @return [AjPHet] Pointer to a Het object
2753 ** @category new [AjPHet] Default Het constructor.
2754 **
2755 ** @release 2.9.0
2756 ** @@
2757 ******************************************************************************/
2758 
ajHetNew(ajuint n)2759 AjPHet ajHetNew(ajuint n)
2760 {
2761     ajuint i = 0U;
2762 
2763     AjPHet het = NULL;
2764 
2765     AJNEW0(het);
2766 
2767     if (n)
2768     {
2769         AJCNEW0(het->Entries, n);
2770 
2771         het->Number = n;
2772 
2773         for (i = 0U; i < n; i++)
2774             het->Entries[i] = ajHetentNew();
2775     }
2776     else
2777     {
2778         het->Number = 0U;
2779         het->Entries = NULL;
2780     }
2781 
2782     return het;
2783 }
2784 
2785 
2786 
2787 
2788 /* @func ajVdwallNew **********************************************************
2789 **
2790 ** Vdwall object constructor. This is normally called by the ajVdwallReadNew
2791 ** function. Fore-knowledge of the number of residues is required.
2792 **
2793 ** @param  [r] n [ajuint] Number of residues
2794 **
2795 ** @return [AjPVdwall] Pointer to a Vdwall object
2796 ** @category new [AjPVdwall] Default Vdwall constructor.
2797 **
2798 ** @release 2.9.0
2799 ** @@
2800 ******************************************************************************/
2801 
ajVdwallNew(ajuint n)2802 AjPVdwall ajVdwallNew(ajuint n)
2803 {
2804     AjPVdwall vdwall = NULL;
2805 
2806     AJNEW0(vdwall);
2807 
2808     vdwall->N = n;
2809 
2810     if (n)
2811         AJCNEW0(vdwall->Res, n);
2812 
2813     return vdwall;
2814 }
2815 
2816 
2817 
2818 
2819 /* @func ajVdwresNew **********************************************************
2820 **
2821 ** Vdwres object constructor. This is normally called by the ajVdwallReadNew
2822 ** function. Fore-knowledge of the number of atoms is required.
2823 **
2824 ** @param  [r] n [ajuint] Number of atoms
2825 **
2826 ** @return [AjPVdwres] Pointer to a Vdwres object
2827 ** @category new [AjPVdwres] Default Vdwres constructor.
2828 **
2829 ** @release 2.9.0
2830 ** @@
2831 ******************************************************************************/
2832 
ajVdwresNew(ajuint n)2833 AjPVdwres ajVdwresNew(ajuint n)
2834 {
2835     ajuint i = 0U;
2836 
2837     AjPVdwres vdwres = NULL;
2838 
2839     AJNEW0(vdwres);
2840 
2841     vdwres->Id3 = ajStrNew();
2842     vdwres->N = n;
2843 
2844     if (n)
2845     {
2846         AJCNEW0(vdwres->Atm, n);
2847 
2848         for (i = 0U; i < n; i++)
2849             vdwres->Atm[i] = ajStrNew();
2850 
2851         AJCNEW0(vdwres->Rad, n);
2852     }
2853 
2854     return vdwres;
2855 }
2856 
2857 
2858 
2859 
2860 /* @func ajCmapNew ************************************************************
2861 **
2862 ** Cmap object constructor. This is normally called by the ajCmapReadNew
2863 ** function. Fore-knowledge of the dimension (number of residues) for the
2864 ** contact map is required.
2865 **
2866 ** @param  [r] n [ajuint] Dimension of contact map
2867 **
2868 ** @return [AjPCmap] Pointer to a Cmap object
2869 **
2870 ** @category new [AjPCmap] Default Cmap constructor.
2871 **
2872 ** @release 2.9.0
2873 ** @@
2874 ******************************************************************************/
2875 
ajCmapNew(ajuint n)2876 AjPCmap ajCmapNew(ajuint n)
2877 {
2878     ajuint i = 0;
2879 
2880     AjPCmap cmap = NULL;
2881 
2882     AJNEW0(cmap);
2883 
2884     cmap->Id = ajStrNew();
2885     cmap->Domid = ajStrNew();
2886     cmap->Ligid = ajStrNew();
2887     cmap->Seq1 = ajStrNew();
2888     cmap->Seq2 = ajStrNew();
2889     cmap->Desc = ajStrNew();
2890     cmap->Chid1 = '.';
2891     cmap->Chid2 = '.';
2892 
2893     if (n)
2894     {
2895         /* Create the SQUARE contact map */
2896         cmap->Mat = ajUint2dNewRes((ajint) n);
2897 
2898         for (i = 0U; i < n; i++)
2899             ajUint2dPut(&cmap->Mat, i, n - 1, 0U);
2900     }
2901 
2902     cmap->Dim = n;
2903     cmap->Ncon = 0;
2904 
2905     return cmap;
2906 }
2907 
2908 
2909 
2910 
2911 /* @func ajPdbtospNew *********************************************************
2912 **
2913 ** Pdbtosp object constructor. Fore-knowledge of the number of entries is
2914 ** required. This is normally called by the ajPdbtospReadCNew /
2915 ** ajPdbtospReadNew functions.
2916 **
2917 ** @param [r] n [ajuint] Number of entries
2918 **
2919 ** @return [AjPPdbtosp] Pointer to a Pdbtosp object
2920 ** @category new [AjPPdbtosp] Default Pdbtosp constructor.
2921 **
2922 ** @release 2.9.0
2923 ** @@
2924 ******************************************************************************/
2925 
ajPdbtospNew(ajuint n)2926 AjPPdbtosp ajPdbtospNew(ajuint n)
2927 {
2928     ajuint i = 0U;
2929 
2930     AjPPdbtosp pdbtosp = NULL;
2931 
2932     AJNEW0(pdbtosp);
2933 
2934     pdbtosp->Pdb = ajStrNew();
2935 
2936     if (n)
2937     {
2938         AJCNEW0(pdbtosp->Acc, n);
2939         AJCNEW0(pdbtosp->Spr, n);
2940 
2941         for (i = 0U; i < n; i++)
2942         {
2943             pdbtosp->Acc[i] = ajStrNew();
2944             pdbtosp->Spr[i] = ajStrNew();
2945         }
2946     }
2947 
2948     pdbtosp->Number = n;
2949 
2950     return pdbtosp;
2951 }
2952 
2953 
2954 
2955 
2956 /* ======================================================================= */
2957 /* =========================== destructors =============================== */
2958 /* ======================================================================= */
2959 
2960 
2961 
2962 
2963 /* @section Destructors *******************************************************
2964 **
2965 ** All destructor functions receive the address of the instance to be
2966 ** deleted.  The original pointer is set to NULL so is ready for re-use.
2967 **
2968 ******************************************************************************/
2969 
2970 
2971 
2972 
2973 /* @func ajAtomDel ************************************************************
2974 **
2975 ** Destructor for an AJAX Atom object.
2976 **
2977 ** @param [d] Patom [AjPAtom*] AJAX Atom address
2978 **
2979 ** @return [void]
2980 ** @category delete [AjPAtom] Default Atom destructor
2981 **
2982 ** @release 1.8.0
2983 ** @@
2984 ******************************************************************************/
2985 
ajAtomDel(AjPAtom * Patom)2986 void ajAtomDel(AjPAtom *Patom)
2987 {
2988     AjPAtom atom = NULL;
2989 
2990     if (!Patom || !*Patom)
2991         return;
2992 
2993     atom = *Patom;
2994 
2995     ajStrDel(&atom->Id3);
2996     ajStrDel(&atom->Atm);
2997     ajStrDel(&atom->Pdb);
2998 #if AJFALSE
2999     ajStrDel(&atom->eId);
3000 #endif
3001     AJFREE(atom);
3002 
3003     *Patom = NULL;
3004 
3005     return;
3006 }
3007 
3008 
3009 
3010 
3011 /* @func ajResidueDel *********************************************************
3012 **
3013 ** Destructor for an AJAX Residue object.
3014 **
3015 ** @param [d] Presidue [AjPResidue*] AJAX Residue address
3016 **
3017 ** @return [void]
3018 ** @category delete [AjPResidue] Default AJAX Residue destructor
3019 **
3020 ** @release 3.0.0
3021 ** @@
3022 ******************************************************************************/
3023 
ajResidueDel(AjPResidue * Presidue)3024 void ajResidueDel(AjPResidue *Presidue)
3025 {
3026     AjPResidue residue = NULL;
3027 
3028     if (!Presidue || !*Presidue)
3029         return;
3030 
3031     residue = *Presidue;
3032 
3033     ajStrDel(&residue->Pdb);
3034     ajStrDel(&residue->Id3);
3035     ajStrDel(&residue->eId);
3036 
3037     AJFREE(residue);
3038 
3039     *Presidue = NULL;
3040 
3041     return;
3042 }
3043 
3044 
3045 
3046 
3047 /* @func ajChainDel ***********************************************************
3048 **
3049 ** Destructor for an AJAX Chain object.
3050 **
3051 ** @param [d] Pchain [AjPChain*] AJAX Chain address
3052 **
3053 ** @return [void]
3054 ** @category delete [AjPChain] Default AJAX Chain destructor.
3055 **
3056 ** @release 1.8.0
3057 ** @@
3058 ******************************************************************************/
3059 
ajChainDel(AjPChain * Pchain)3060 void ajChainDel(AjPChain *Pchain)
3061 {
3062     AjPAtom atom = NULL;
3063 
3064     AjPChain chain = NULL;
3065 
3066     AjPResidue residue = NULL;
3067 
3068     if (!Pchain || !*Pchain)
3069         return;
3070 
3071     chain = *Pchain;
3072 
3073     while (ajListPop(chain->Atoms, (void **) &atom))
3074         ajAtomDel(&atom);
3075 
3076     ajListFree(&chain->Atoms);
3077 
3078     while (ajListPop(chain->Residues, (void **) &residue))
3079         ajResidueDel(&residue);
3080 
3081     ajListFree(&chain->Residues);
3082 
3083     ajStrDel(&chain->Seq);
3084 
3085     AJFREE(chain);
3086 
3087     *Pchain = NULL;
3088 
3089     return;
3090 }
3091 
3092 
3093 
3094 
3095 /* @func ajPdbDel *************************************************************
3096 **
3097 ** Destructor for an AJAX PDB object.
3098 **
3099 ** @param [d] Ppdb [AjPPdb*] AJAX PDB address
3100 **
3101 ** @return [void]
3102 ** @category delete [AjPPdb] Default AJAX PDB destructor.
3103 **
3104 ** @release 1.8.0
3105 ** @@
3106 ******************************************************************************/
3107 
ajPdbDel(AjPPdb * Ppdb)3108 void ajPdbDel(AjPPdb *Ppdb)
3109 {
3110     ajuint i = 0U;
3111 
3112     AjPAtom atom = NULL;
3113 
3114     AjPPdb pdb = NULL;
3115 
3116     if (!Ppdb || !*Ppdb)
3117         return;
3118 
3119     pdb = *Ppdb;
3120 
3121     ajStrDel(&pdb->Pdb);
3122     ajStrDel(&pdb->Compnd);
3123     ajStrDel(&pdb->Source);
3124 
3125     ajChararrDel(&pdb->gpid);
3126 
3127     while (ajListPop(pdb->Water, (void **) &atom))
3128         ajAtomDel(&atom);
3129 
3130     ajListFree(&pdb->Water);
3131 
3132     while (ajListPop(pdb->Groups, (void **) &atom))
3133         ajAtomDel(&atom);
3134 
3135     ajListFree(&pdb->Groups);
3136 
3137     for (i = 0U; i < pdb->Nchn; i++)
3138         ajChainDel(&pdb->Chains[i]);
3139 
3140     AJFREE(pdb->Chains);
3141 
3142     AJFREE(pdb);
3143 
3144     *Ppdb = NULL;
3145 
3146     return;
3147 }
3148 
3149 
3150 
3151 
3152 /* @func ajHetentDel **********************************************************
3153 **
3154 ** Destructor for an AJAX Hetent object.
3155 **
3156 ** @param [d] Phetent [AjPHetent*] AJAX Hetent address
3157 **
3158 ** @return [void]
3159 ** @category delete [AjPHetent] Default AJAX Hetent destructor.
3160 **
3161 ** @release 2.9.0
3162 ** @@
3163 ******************************************************************************/
3164 
ajHetentDel(AjPHetent * Phetent)3165 void ajHetentDel(AjPHetent *Phetent)
3166 {
3167     AjPHetent hetent = NULL;
3168 
3169     if (!Phetent || !*Phetent)
3170         return;
3171 
3172     hetent = *Phetent;
3173 
3174     ajStrDel(&hetent->abv);
3175     ajStrDel(&hetent->syn);
3176     ajStrDel(&hetent->ful);
3177 
3178     AJFREE(hetent);
3179 
3180     *Phetent = NULL;
3181 
3182     return;
3183 }
3184 
3185 
3186 
3187 
3188 /* @func ajHetDel *************************************************************
3189 **
3190 ** Destructor for an AJAX Het object.
3191 **
3192 ** @param [d] Phet [AjPHet*] AJAX Het address
3193 **
3194 ** @return [void]
3195 ** @category delete [AjPHet] Default AJAX Het destructor.
3196 **
3197 ** @release 2.9.0
3198 ** @@
3199 ******************************************************************************/
3200 
ajHetDel(AjPHet * Phet)3201 void ajHetDel(AjPHet *Phet)
3202 {
3203     ajuint i = 0U;
3204 
3205     AjPHet het = NULL;
3206 
3207     if (!Phet || !*Phet)
3208         return;
3209 
3210     het = *Phet;
3211 
3212     if (het->Entries)
3213     {
3214         for (i = 0U; i < het->Number; i++)
3215             ajHetentDel(&het->Entries[i]);
3216 
3217         AJFREE(het->Entries);
3218     }
3219 
3220     AJFREE(het);
3221 
3222     *Phet = NULL;
3223 
3224     return;
3225 }
3226 
3227 
3228 
3229 
3230 /* @func ajVdwallDel **********************************************************
3231 **
3232 ** Destructor for an AJAX Vdwall object.
3233 **
3234 ** @param [d] Pvdwall [AjPVdwall*] AJAX Vdwall address
3235 **
3236 ** @return [void]
3237 ** @category delete [AjPVdwall] Default AJAX Vdwall destructor.
3238 **
3239 ** @release 2.9.0
3240 ** @@
3241 ******************************************************************************/
3242 
ajVdwallDel(AjPVdwall * Pvdwall)3243 void ajVdwallDel(AjPVdwall *Pvdwall)
3244 {
3245     ajuint i = 0U;
3246 
3247     AjPVdwall vdwall = NULL;
3248 
3249     if(!Pvdwall || !*Pvdwall)
3250         return;
3251 
3252     vdwall = *Pvdwall;
3253 
3254     for (i = 0U; i < vdwall->N; i++)
3255         ajVdwresDel(&vdwall->Res[i]);
3256 
3257     AJFREE(vdwall->Res);
3258     AJFREE(vdwall);
3259 
3260     *Pvdwall = NULL;
3261 
3262     return;
3263 }
3264 
3265 
3266 
3267 
3268 /* @func ajVdwresDel **********************************************************
3269 **
3270 ** Destructor for an AJAX Vdwres object.
3271 **
3272 ** @param [d] Pvdwres [AjPVdwres*] AJAX Vdwres address
3273 **
3274 ** @return [void]
3275 ** @category delete [AjPVdwres] Default AJAX Vdwres destructor.
3276 **
3277 ** @release 2.9.0
3278 ** @@
3279 ******************************************************************************/
3280 
ajVdwresDel(AjPVdwres * Pvdwres)3281 void ajVdwresDel(AjPVdwres *Pvdwres)
3282 {
3283     ajuint i = 0U;
3284 
3285     AjPVdwres vdwres = NULL;
3286 
3287     if(!Pvdwres || !*Pvdwres)
3288         return;
3289 
3290     vdwres = *Pvdwres;
3291 
3292     ajStrDel(&vdwres->Id3);
3293 
3294     for (i = 0U; i < vdwres->N; i++)
3295         ajStrDel(&vdwres->Atm[i]);
3296 
3297     AJFREE(vdwres->Atm);
3298     AJFREE(vdwres->Rad);
3299     AJFREE(vdwres);
3300 
3301     *Pvdwres = NULL;
3302 
3303     return;
3304 }
3305 
3306 
3307 
3308 
3309 /* @func ajCmapDel ************************************************************
3310 **
3311 ** Destructor for an AJAX Cmap object.
3312 **
3313 ** @param [d] Pcmap [AjPCmap*] AJAX Cmap address
3314 **
3315 ** @return [void]
3316 ** @category delete [AjPCmap] Default AJAX Cmap destructor.
3317 **
3318 ** @release 2.9.0
3319 ** @@
3320 ******************************************************************************/
3321 
ajCmapDel(AjPCmap * Pcmap)3322 void ajCmapDel(AjPCmap *Pcmap)
3323 {
3324     AjPCmap cmap = NULL;
3325 
3326     if (!Pcmap || !*Pcmap)
3327         return;
3328 
3329     cmap = *Pcmap;
3330 
3331     ajStrDel(&cmap->Id);
3332     ajStrDel(&cmap->Domid);
3333     ajStrDel(&cmap->Ligid);
3334     ajStrDel(&cmap->Seq1);
3335     ajStrDel(&cmap->Seq2);
3336     ajStrDel(&cmap->Desc);
3337 
3338     ajUint2dDel(&cmap->Mat);
3339 
3340     AJFREE(cmap);
3341 
3342     *Pcmap = NULL;
3343 
3344     return;
3345 }
3346 
3347 
3348 
3349 
3350 /* @func ajPdbtospDel *********************************************************
3351 **
3352 ** Destructor for an AJAX Pdbtosp object.
3353 **
3354 ** @param [d] Ppdbtosp [AjPPdbtosp*] AJAX Pdbtosp address
3355 **
3356 ** @return [void]
3357 ** @category delete [AjPPdbtosp] Default AJAX Pdbtosp destructor.
3358 **
3359 ** @release 2.9.0
3360 ** @@
3361 ******************************************************************************/
3362 
ajPdbtospDel(AjPPdbtosp * Ppdbtosp)3363 void ajPdbtospDel(AjPPdbtosp *Ppdbtosp)
3364 {
3365     ajuint i = 0U;
3366 
3367     AjPPdbtosp pdbtosp = NULL;
3368 
3369     if (!Ppdbtosp || !*Ppdbtosp)
3370         return;
3371 
3372     pdbtosp = *Ppdbtosp;
3373 
3374     ajStrDel(&pdbtosp->Pdb);
3375 
3376     if (pdbtosp->Number)
3377     {
3378         for (i = 0U; i < pdbtosp->Number; i++)
3379         {
3380             ajStrDel(&pdbtosp->Acc[i]);
3381             ajStrDel(&pdbtosp->Spr[i]);
3382         }
3383 
3384         AJFREE(pdbtosp->Acc);
3385         AJFREE(pdbtosp->Spr);
3386     }
3387 
3388     AJFREE(pdbtosp);
3389 
3390     *Ppdbtosp = NULL;
3391 
3392     return;
3393 }
3394 
3395 
3396 
3397 
3398 /* ======================================================================= */
3399 /* ============================ Assignments ============================== */
3400 /* ======================================================================= */
3401 
3402 
3403 
3404 
3405 /* @section Assignments *******************************************************
3406 **
3407 ** These functions overwrite the instance provided as the first argument
3408 ** A NULL value is always acceptable so these functions are often used to
3409 ** create a new instance by assignment.
3410 **
3411 ******************************************************************************/
3412 
3413 
3414 
3415 
3416 /* @func ajAtomCopy ***********************************************************
3417 **
3418 ** Copies the data from an AJAX Atom object to an AJAX Atom object;
3419 ** the new object is created if needed.
3420 **
3421 ** IMPORTANT - THIS DOES NOT COPY THE eNum & eType ELEMENTS, WHICH ARE SET
3422 ** TO ZERO and '.' INSTEAD.
3423 **
3424 ** @param [w] Pto  [AjPAtom*] AJAX Atom address
3425 ** @param [r] from [const AjPAtom] AJAX Atom
3426 **
3427 ** @return [AjBool] True on success
3428 **
3429 ** @release 2.9.0
3430 ** @@
3431 ******************************************************************************/
3432 
ajAtomCopy(AjPAtom * Pto,const AjPAtom from)3433 AjBool ajAtomCopy(AjPAtom *Pto, const AjPAtom from)
3434 {
3435     if (!Pto)
3436     {
3437         ajWarn("Bad arg (NULL) passed to ajAtomCopy");
3438         return ajFalse;
3439     }
3440 
3441     if (!*Pto)
3442         *Pto = ajAtomNew();
3443 
3444     (*Pto)->Mod = from->Mod;
3445     (*Pto)->Chn = from->Chn;
3446     (*Pto)->Gpn = from->Gpn;
3447     (*Pto)->Idx = from->Idx;
3448     ajStrAssignS(&((*Pto)->Pdb), from->Pdb);
3449     (*Pto)->Id1 = from->Id1;
3450     ajStrAssignS(&((*Pto)->Id3), from->Id3);
3451     (*Pto)->Type = from->Type;
3452     ajStrAssignS(&((*Pto)->Atm), from->Atm);
3453     (*Pto)->X = from->X;
3454     (*Pto)->Y = from->Y;
3455     (*Pto)->Z = from->Z;
3456     (*Pto)->O = from->O;
3457     (*Pto)->B = from->B;
3458 
3459     return ajTrue;
3460 }
3461 
3462 
3463 
3464 
3465 /* @func ajResidueCopy ********************************************************
3466 **
3467 ** Copies the data from a Residue object to an Residue object; the new object
3468 ** is created if needed.
3469 **
3470 ** IMPORTANT - THIS DOES NOT COPY THE eNum & eType ELEMENTS, WHICH ARE SET
3471 ** TO ZERO and '.' INSTEAD.
3472 **
3473 ** @param [w] Pto  [AjPResidue*] AJAX Residue address
3474 ** @param [r] from [const AjPResidue] AJAX Residue
3475 **
3476 ** @return [AjBool] True on success
3477 **
3478 ** @release 3.0.0
3479 ** @@
3480 ******************************************************************************/
3481 
ajResidueCopy(AjPResidue * Pto,const AjPResidue from)3482 AjBool ajResidueCopy(AjPResidue *Pto, const AjPResidue from)
3483 {
3484     if (!Pto)
3485     {
3486         ajWarn("Bad arg (NULL) passed to ajResidueCopy");
3487 
3488         return ajFalse;
3489     }
3490 
3491     if (!*Pto)
3492         *Pto = ajResidueNew();
3493 
3494     (*Pto)->Mod = from->Mod;
3495     (*Pto)->Chn = from->Chn;
3496     (*Pto)->Idx = from->Idx;
3497     ajStrAssignS(&((*Pto)->Pdb), from->Pdb);
3498     (*Pto)->Id1 = from->Id1;
3499     ajStrAssignS(&((*Pto)->Id3), from->Id3);
3500     (*Pto)->Phi = from->Phi;
3501     (*Pto)->Psi = from->Psi;
3502     (*Pto)->Area = from->Area;
3503 
3504     (*Pto)->eNum = from->eNum;
3505     ajStrAssignS(&((*Pto)->eId), from->eId);
3506     (*Pto)->eType = from->eType;
3507     (*Pto)->eClass = from->eClass;
3508     (*Pto)->eStrideNum = from->eStrideNum;
3509     (*Pto)->eStrideType = from->eStrideType;
3510 
3511     (*Pto)->all_abs = from->all_abs;
3512     (*Pto)->all_rel = from->all_rel;
3513     (*Pto)->side_abs = from->side_abs;
3514     (*Pto)->side_rel = from->side_rel;
3515     (*Pto)->main_abs = from->main_abs;
3516     (*Pto)->main_rel = from->main_rel;
3517     (*Pto)->npol_abs = from->npol_abs;
3518     (*Pto)->npol_rel = from->npol_rel;
3519     (*Pto)->pol_abs = from->pol_abs;
3520     (*Pto)->pol_rel = from->pol_rel;
3521 
3522     return ajTrue;
3523 }
3524 
3525 
3526 
3527 
3528 /* @func ajAtomListCopy *******************************************************
3529 **
3530 ** Read a list of Atom structures and writes a copy of the list.  The
3531 ** data are copied and the list is created if necessary.
3532 **
3533 ** @param [w] Pto      [AjPList*] AJAX List of AJAX Atom objects to write
3534 ** @param [r] from     [const AjPList]   List of Atom objects to read
3535 **
3536 ** @return [AjBool] True if list was copied ok.
3537 **
3538 ** @release 2.9.0
3539 ** @@
3540 ******************************************************************************/
3541 
ajAtomListCopy(AjPList * Pto,const AjPList from)3542 AjBool ajAtomListCopy(AjPList *Pto, const AjPList from)
3543 {
3544     AjIList iter = NULL;
3545     AjPAtom hit = NULL;
3546     AjPAtom new = NULL;
3547 
3548     /* Check arg's */
3549     if (!from || !Pto)
3550     {
3551         ajWarn("Bad arg's passed to ajAtomListCopy\n");
3552         return ajFalse;
3553     }
3554 
3555     /* Allocate the new list, if necessary */
3556     if (!*Pto)
3557         *Pto = ajListNew();
3558 
3559     /* Initialise the iterator */
3560     iter = ajListIterNewread(from);
3561 
3562     /* Iterate through the list of Atom objects */
3563     while ((hit = (AjPAtom) ajListIterGet(iter)))
3564     {
3565         new = ajAtomNew();
3566 
3567         ajAtomCopy(&new, hit);
3568 
3569         /* Push scophit onto list */
3570         ajListPushAppend(*Pto, new);
3571     }
3572 
3573     ajListIterDel(&iter);
3574 
3575     return ajTrue;
3576 }
3577 
3578 
3579 
3580 
3581 /* @func ajResidueListCopy ****************************************************
3582 **
3583 ** Read a list of Residue structures and writes a copy of the list.  The
3584 ** data are copied and the list is created if necessary.
3585 **
3586 ** @param [w] to       [AjPList *] List of Residue objects to write
3587 ** @param [r] from     [const AjPList]   List of Residue objects to read
3588 **
3589 ** @return [AjBool] True if list was copied ok.
3590 **
3591 ** @release 3.0.0
3592 ** @@
3593 ******************************************************************************/
3594 
ajResidueListCopy(AjPList * to,const AjPList from)3595 AjBool ajResidueListCopy(AjPList *to, const AjPList from)
3596 {
3597     AjIList iter = NULL;
3598     AjPResidue hit = NULL;
3599     AjPResidue new = NULL;
3600 
3601     /* Check arg's */
3602     if (!from || !to)
3603     {
3604         ajWarn("Bad arg's passed to ajResidueListCopy\n");
3605         return ajFalse;
3606     }
3607 
3608     /* Allocate the new list, if necessary */
3609     if (!(*to))
3610         *to = ajListNew();
3611 
3612     /* Initialise the iterator */
3613     iter = ajListIterNewread(from);
3614 
3615     /* Iterate through the list of Atom objects */
3616     while ((hit = (AjPResidue) ajListIterGet(iter)))
3617     {
3618         new = ajResidueNew();
3619 
3620         ajResidueCopy(&new, hit);
3621 
3622         /* Push scophit onto list */
3623         ajListPushAppend(*to, new);
3624     }
3625 
3626     ajListIterDel(&iter);
3627     return ajTrue;
3628 }
3629 
3630 
3631 
3632 
3633 /* @func ajPdbCopy ************************************************************
3634 **
3635 ** Copies data from one AHAX PDB object to another; the new object is
3636 ** always created.
3637 **
3638 **
3639 ** @param [w] Pto  [AjPPdb*] AJAX PDB address
3640 ** @param [r] from [const AjPPdb] AJAX PDB
3641 **
3642 ** @return [AjBool] True on success
3643 **
3644 ** @release 2.9.0
3645 ** @@
3646 ******************************************************************************/
3647 
ajPdbCopy(AjPPdb * Pto,const AjPPdb from)3648 AjBool ajPdbCopy(AjPPdb *Pto, const AjPPdb from)
3649 {
3650     ajuint i = 0U;
3651 
3652     if (!from)
3653     {
3654         ajWarn("NULL arg passed to ajPdbCopy");
3655 
3656         return ajFalse;
3657     }
3658 
3659     if ((*Pto))
3660     {
3661         ajWarn("Pointer passed to ajPdbCopy should be NULL but isn't !");
3662 
3663         return ajFalse;
3664     }
3665 
3666     /* Copy data in Pdb object */
3667     (*Pto) = ajPdbNew(from->Nchn);
3668     ajStrAssignS(&((*Pto)->Pdb), from->Pdb);
3669     ajStrAssignS(&((*Pto)->Compnd), from->Compnd);
3670     ajStrAssignS(&((*Pto)->Source), from->Source);
3671     (*Pto)->Method = from->Method;
3672     (*Pto)->Reso = from->Reso;
3673     (*Pto)->Nmod = from->Nmod;
3674     (*Pto)->Nchn = from->Nchn;
3675     (*Pto)->Ngp = from->Ngp;
3676 
3677     for (i = 0U; i < from->Ngp; i++)
3678         ajChararrPut(&((*Pto)->gpid), i, ajChararrGet(from->gpid, i));
3679 
3680     ajListFree(&((*Pto)->Groups));
3681     ajListFree(&((*Pto)->Water));
3682 
3683 #if AJFALSE
3684     (*Pto)->Groups = ajAtomListCopy(from->Groups);
3685     (*Pto)->Water = ajAtomListCopy(from->Water);
3686 #endif
3687     if (!ajAtomListCopy(&(*Pto)->Groups, from->Groups))
3688         ajFatal("Error copying Groups list");
3689 
3690     if (!ajAtomListCopy(&(*Pto)->Water, from->Water))
3691         ajFatal("Error copying Water list");
3692 
3693     /* Copy data in Chain objects */
3694     for (i = 0; i < from->Nchn; i++)
3695     {
3696         ajListFree(&((*Pto)->Chains[i]->Atoms));
3697 
3698         (*Pto)->Chains[i]->Id = from->Chains[i]->Id;
3699         (*Pto)->Chains[i]->Nres = from->Chains[i]->Nres;
3700         (*Pto)->Chains[i]->Nlig = from->Chains[i]->Nlig;
3701         (*Pto)->Chains[i]->numHelices = from->Chains[i]->numHelices;
3702         (*Pto)->Chains[i]->numStrands = from->Chains[i]->numStrands;
3703         ajStrAssignS(&((*Pto)->Chains[i]->Seq), from->Chains[i]->Seq);
3704 #if AJFALSE
3705         (*Pto)->Chains[i]->Atoms = ajAtomListCopy(from->Chains[i]->Atoms);
3706 #endif
3707         if (!ajAtomListCopy(&(*Pto)->Chains[i]->Atoms, from->Chains[i]->Atoms))
3708             ajFatal("Error copying Atoms list");
3709         if (!ajResidueListCopy(&(*Pto)->Chains[i]->Residues,
3710                                from->Chains[i]->Residues))
3711             ajFatal("Error copying Residues list");
3712     }
3713 
3714     return ajTrue;
3715 }
3716 
3717 
3718 
3719 
3720 /* ======================================================================= */
3721 /* ============================= Modifiers =============================== */
3722 /* ======================================================================= */
3723 
3724 
3725 
3726 
3727 /* @section Modifiers *********************************************************
3728 **
3729 ** These functions use the contents of an instance and update them.
3730 **
3731 ******************************************************************************/
3732 
3733 
3734 
3735 
3736 /* ======================================================================= */
3737 /* ========================== Operators ===================================*/
3738 /* ======================================================================= */
3739 
3740 
3741 
3742 
3743 /* @section Operators *********************************************************
3744 **
3745 ** These functions use the contents of an instance but do not make any
3746 ** changes.
3747 **
3748 ******************************************************************************/
3749 
3750 
3751 
3752 
3753 /* @func ajResidueSSEnv *******************************************************
3754 **
3755 ** Assigns secondary structure environment of an AJAX Residue
3756 **
3757 ** @param  [r] residue [const AjPResidue] AJAX Residue
3758 ** @param  [w] SEnv [char*] Character for the Secondary structure environment
3759 ** @param  [w] flog [AjPFile] Log file
3760 ** @return [AjBool] ajTrue on success
3761 **
3762 ** @release 3.0.0
3763 ** @@
3764 ******************************************************************************/
3765 
ajResidueSSEnv(const AjPResidue residue,char * SEnv,AjPFile flog)3766 AjBool ajResidueSSEnv(const AjPResidue residue, char *SEnv, AjPFile flog)
3767 {
3768     *SEnv = '\0';
3769     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f\n", residue->Id1, residue->Idx,
3770                 residue->eStrideType, residue->side_rel);
3771 
3772     if (residue->eStrideType == 'H' ||
3773         residue->eStrideType == 'G')
3774         *SEnv = 'H';
3775     else if (residue->eStrideType == 'E' ||
3776              residue->eStrideType == 'B' ||
3777              residue->eStrideType == 'b')
3778         *SEnv = 'S';
3779     else if (residue->eStrideType == 'T' ||
3780              residue->eStrideType == 'C' ||
3781              residue->eStrideType == 'I')
3782         *SEnv = 'C';
3783     /* If no stride assignment, get pdb assignment */
3784     else if (residue->eStrideType == '.')
3785     {
3786         if (residue->eType == 'H')
3787             *SEnv = 'H';
3788         else if (residue->eType == 'E')
3789             *SEnv = 'S';
3790         else if (residue->eType == 'C' ||
3791                  residue->eType == 'T')
3792             *SEnv = 'C';
3793         else if (residue->eType == '.')
3794         {
3795             ajFmtPrintF(flog, "SEnv unknown for residue %d\n", residue->Idx);
3796             /* *SEnv='C'; */
3797             *SEnv = '\0';
3798             return ajFalse;
3799         }
3800     }
3801 
3802     return ajTrue;
3803 }
3804 
3805 
3806 
3807 
3808 /* @func ajResidueEnv1 ********************************************************
3809 **
3810 ** Assigns environment based only of side chain accessibility and secondary
3811 ** structure.  Assigns environment of "*" as default.
3812 **
3813 ** @param [r] residue [const AjPResidue] AJAX Residue
3814 ** @param [r] SEnv [char]          Secondary structure environment code
3815 ** @param [w] OEnv [AjPStr*]       Character for the overall environment class
3816 ** @param  [w] flog [AjPFile] Log file
3817 ** @return [ajint] Number of environments
3818 **
3819 ** @release 3.0.0
3820 ** @@
3821 ******************************************************************************/
3822 
ajResidueEnv1(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)3823 ajint ajResidueEnv1(const AjPResidue residue, char SEnv, AjPStr *OEnv,
3824                     AjPFile flog)
3825 {
3826     if (SEnv == '\0')
3827     {
3828         ajStrSetClear(OEnv);
3829 
3830         return 0;
3831     }
3832 
3833     if ((residue->side_rel <= 15) && (SEnv == 'H'))
3834         ajStrAssignC(OEnv, "AA");
3835     else if ((residue->side_rel <= 15) && (SEnv == 'S'))
3836         ajStrAssignC(OEnv, "AB");
3837     else if ((residue->side_rel <= 15) && (SEnv == 'C'))
3838         ajStrAssignC(OEnv, "AC");
3839     else if ((residue->side_rel > 15) &&
3840              (residue->side_rel <= 30) && (SEnv == 'H'))
3841         ajStrAssignC(OEnv, "AD");
3842     else if ((residue->side_rel > 15) &&
3843              (residue->side_rel <= 30) && (SEnv == 'S'))
3844         ajStrAssignC(OEnv, "AE");
3845     else if ((residue->side_rel > 15) &&
3846              (residue->side_rel <= 30) && (SEnv == 'C'))
3847         ajStrAssignC(OEnv, "AF");
3848     else if ((residue->side_rel > 30) &&
3849              (residue->side_rel <= 45) && (SEnv == 'H'))
3850         ajStrAssignC(OEnv, "AG");
3851     else if ((residue->side_rel > 30) &&
3852              (residue->side_rel <= 45) && (SEnv == 'S'))
3853         ajStrAssignC(OEnv, "AH");
3854     else if ((residue->side_rel > 30) &&
3855              (residue->side_rel <= 45) && (SEnv == 'C'))
3856         ajStrAssignC(OEnv, "AI");
3857     else if ((residue->side_rel > 45) &&
3858              (residue->side_rel <= 60) && (SEnv == 'H'))
3859         ajStrAssignC(OEnv, "AJ");
3860     else if ((residue->side_rel > 45) &&
3861              (residue->side_rel <= 60) && (SEnv == 'S'))
3862         ajStrAssignC(OEnv, "AK");
3863     else if ((residue->side_rel > 45) &&
3864              (residue->side_rel <= 60) && (SEnv == 'C'))
3865         ajStrAssignC(OEnv, "AL");
3866     else if ((residue->side_rel > 60) &&
3867              (residue->side_rel <= 75) && (SEnv == 'H'))
3868         ajStrAssignC(OEnv, "AM");
3869     else if ((residue->side_rel > 60) &&
3870              (residue->side_rel <= 75) && (SEnv == 'S'))
3871         ajStrAssignC(OEnv, "AN");
3872     else if ((residue->side_rel > 60) &&
3873              (residue->side_rel <= 75) && (SEnv == 'C'))
3874         ajStrAssignC(OEnv, "AO");
3875     else if ((residue->side_rel > 75) &&
3876              (residue->side_rel <= 90) && (SEnv == 'H'))
3877         ajStrAssignC(OEnv, "AP");
3878     else if ((residue->side_rel > 75) &&
3879              (residue->side_rel <= 90) && (SEnv == 'S'))
3880         ajStrAssignC(OEnv, "AQ");
3881     else if ((residue->side_rel > 75) &&
3882              (residue->side_rel <= 90) && (SEnv == 'C'))
3883         ajStrAssignC(OEnv, "AR");
3884     else if ((residue->side_rel > 90) && (SEnv == 'H'))
3885         ajStrAssignC(OEnv, "AS");
3886     else if ((residue->side_rel > 90) && (SEnv == 'S'))
3887         ajStrAssignC(OEnv, "AT");
3888     else if ((residue->side_rel > 90) && (SEnv == 'C'))
3889         ajStrAssignC(OEnv, "AU");
3890     else
3891     {
3892         ajStrSetClear(OEnv);
3893         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
3894         return 0;
3895     }
3896 
3897     /* The total number of environments */
3898     return 21;
3899 }
3900 
3901 
3902 
3903 
3904 /* @func ajResidueEnv2 ********************************************************
3905 **
3906 ** Assigns environment based on side chain accessibility and secondary
3907 ** structure.  Assigns environment of "*" as default.
3908 **
3909 ** @param [r] residue [const AjPResidue] AJAX Residue
3910 ** @param [r] SEnv [char] Secondary structure environment code
3911 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
3912 ** @param  [w] flog [AjPFile] Log file
3913 ** @return [ajint] Number of environments
3914 **
3915 ** @release 3.0.0
3916 ** @@
3917 ******************************************************************************/
3918 
ajResidueEnv2(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)3919 ajint ajResidueEnv2(const AjPResidue residue, char SEnv, AjPStr *OEnv,
3920                     AjPFile flog)
3921 {
3922     float BLimit = 40.0F;       /* Upper limit for the relative solvent
3923                                  * accessible area for a buried residue */
3924     float PBLimit = 114.0F;     /* Upper limit for the relative solvent
3925                                  * accessible area for a Partially buried
3926                                  * residue */
3927 
3928     float HLimit = 45.0F;       /* Upper limit for the fraction polar measure
3929                                  * of a Hydrophobic residue */
3930     float MPLimit = 67.0F;      /* Upper limit for the fraction polar measure
3931                                  * of a Moderately polar residue */
3932 
3933     AjPStr BEnv = NULL;
3934 
3935     if (!residue)
3936     {
3937         ajWarn("No residue to ajResidueEnv");
3938 
3939         return 0;
3940     }
3941 
3942     ajStrSetClear(OEnv);
3943     BEnv = ajStrNew();
3944 
3945     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
3946                 residue->Id1, residue->Idx, residue->eType,
3947                 residue->side_rel, residue->pol_rel);
3948 
3949     /* Assign the basic classes */
3950 
3951     /* Buried, Hydrophobic */
3952     if ((residue->side_rel <= BLimit) &&
3953         (residue->pol_rel <= HLimit))
3954         ajStrAssignC(&BEnv, "B1");
3955     /* buried, moderately polar */
3956     else if ((residue->side_rel <= BLimit) &&
3957              (residue->pol_rel > HLimit) &&
3958              (residue->pol_rel <= MPLimit))
3959         ajStrAssignC(&BEnv, "B2");
3960     /* buried, polar */
3961     else if ((residue->side_rel <= BLimit) &&
3962              (residue->pol_rel > MPLimit))
3963         ajStrAssignC(&BEnv, "B3");
3964     /* Partially buried, moderately Polar */
3965     else if ((residue->side_rel > BLimit) &&
3966              (residue->side_rel <= PBLimit) &&
3967              (residue->pol_rel <= MPLimit))
3968         ajStrAssignC(&BEnv, "P1");
3969     /* Partially buried, Polar */
3970     else if ((residue->side_rel > BLimit) &&
3971              (residue->side_rel <= PBLimit) &&
3972              (residue->pol_rel > MPLimit))
3973         ajStrAssignC(&BEnv, "P2");
3974     /* Exposed */
3975     else if (residue->side_rel > PBLimit)
3976         ajStrAssignC(&BEnv, "E");
3977     else
3978     {
3979         ajStrSetClear(OEnv);
3980         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
3981         ajStrDel(&BEnv);
3982         return 0;
3983     }
3984 
3985     /* Assign overall environment class */
3986     if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'H'))
3987         ajStrAssignC(OEnv, "AA");
3988     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'S'))
3989         ajStrAssignC(OEnv, "AB");
3990     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'C'))
3991         ajStrAssignC(OEnv, "AC");
3992     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'H'))
3993         ajStrAssignC(OEnv, "AD");
3994     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'S'))
3995         ajStrAssignC(OEnv, "AE");
3996     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'C'))
3997         ajStrAssignC(OEnv, "AF");
3998     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'H'))
3999         ajStrAssignC(OEnv, "AG");
4000     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'S'))
4001         ajStrAssignC(OEnv, "AH");
4002     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'C'))
4003         ajStrAssignC(OEnv, "AI");
4004     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'H'))
4005         ajStrAssignC(OEnv, "AJ");
4006     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'S'))
4007         ajStrAssignC(OEnv, "AK");
4008     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'C'))
4009         ajStrAssignC(OEnv, "AL");
4010     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'H'))
4011         ajStrAssignC(OEnv, "AM");
4012     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'S'))
4013         ajStrAssignC(OEnv, "AN");
4014     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'C'))
4015         ajStrAssignC(OEnv, "AO");
4016     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'H'))
4017         ajStrAssignC(OEnv, "AP");
4018     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'S'))
4019         ajStrAssignC(OEnv, "AQ");
4020     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'C'))
4021         ajStrAssignC(OEnv, "AR");
4022     else
4023     {
4024         ajStrSetClear(OEnv);
4025         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
4026         ajStrDel(&BEnv);
4027 
4028         return 0;
4029     }
4030 
4031     ajStrDel(&BEnv);
4032 
4033     return 18;
4034 
4035 }
4036 
4037 
4038 
4039 
4040 /* @func ajResidueEnv3 ********************************************************
4041 **
4042 ** Assigns environment based on side chain accessibility and secondary
4043 ** structure.  Assigns environment of "*" as default.
4044 **
4045 ** @param [r] residue [const AjPResidue] AJAX Residue
4046 ** @param [r] SEnv [char] Secondary structure environment code
4047 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
4048 ** @param  [w] flog [AjPFile] Log file
4049 ** @return [ajint] Number of environments
4050 **
4051 ** @release 3.0.0
4052 ** @@
4053 ******************************************************************************/
4054 
ajResidueEnv3(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)4055 ajint ajResidueEnv3(const AjPResidue residue, char SEnv, AjPStr *OEnv,
4056                     AjPFile flog)
4057 {
4058     float BLimit = 5.0F;        /* Upper limit for the relative solvent
4059                                  * accessible area for a buried residue */
4060     float PBLimit = 25.0F;      /* Upper limit for the relative solvent
4061                                  * accessible area for a Partially buried
4062                                  * residue */
4063 
4064     float PolLimit1 = 10.0F;
4065     float PolLimit2 = 30.0F;
4066     float PolLimit3 = 50.0F;
4067     float PolLimit4 = 80.0F;
4068 
4069     AjPStr BEnv = NULL;
4070 
4071     if (!residue)
4072     {
4073         ajWarn("No residue to ajResidueEnv");
4074 
4075         return 0;
4076     }
4077 
4078     ajStrSetClear(OEnv);
4079     BEnv = ajStrNew();
4080 
4081     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
4082                 residue->Id1, residue->Idx, residue->eType,
4083                 residue->side_rel, residue->pol_rel);
4084 
4085     /* Assign the basic classes */
4086 
4087     /* Buried, Hydrophobic */
4088     if ((residue->side_rel <= BLimit) &&
4089         (residue->pol_rel <= PolLimit1))
4090         ajStrAssignC(&BEnv, "B1");
4091     /* buried, moderately polar */
4092     else if ((residue->side_rel <= BLimit) &&
4093              (residue->pol_rel > PolLimit1) &&
4094              (residue->pol_rel <= PolLimit2))
4095         ajStrAssignC(&BEnv, "B2");
4096     else if ((residue->side_rel <= BLimit) &&
4097              (residue->pol_rel > PolLimit2) &&
4098              (residue->pol_rel <= PolLimit3))
4099         ajStrAssignC(&BEnv, "B3");
4100     else if ((residue->side_rel <= BLimit) &&
4101              (residue->pol_rel > PolLimit3) &&
4102              (residue->pol_rel <= PolLimit4))
4103         ajStrAssignC(&BEnv, "B4");
4104     else if ((residue->side_rel <= BLimit) &&
4105              (residue->pol_rel > PolLimit4))
4106         ajStrAssignC(&BEnv, "B5");
4107     /* Partially buried, moderately Polar */
4108     else if ((residue->side_rel > BLimit) &&
4109              (residue->side_rel <= PBLimit) &&
4110              (residue->pol_rel <= PolLimit3))
4111         ajStrAssignC(&BEnv, "P1");
4112     /* Partially buried, Polar */
4113     else if ((residue->side_rel > BLimit) &&
4114              (residue->side_rel <= PBLimit) &&
4115              (residue->pol_rel > PolLimit3))
4116         ajStrAssignC(&BEnv, "P2");
4117     /* Exposed */
4118     else if (residue->side_rel > PBLimit)
4119         ajStrAssignC(&BEnv, "E");
4120     else
4121     {
4122         ajStrSetClear(OEnv);
4123         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
4124 
4125         ajStrDel(&BEnv);
4126         return 0;
4127     }
4128 
4129     /* Assign overall environment class */
4130     if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'H'))
4131         ajStrAssignC(OEnv, "AA");
4132     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'S'))
4133         ajStrAssignC(OEnv, "AB");
4134     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'C'))
4135         ajStrAssignC(OEnv, "AC");
4136     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'H'))
4137         ajStrAssignC(OEnv, "AD");
4138     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'S'))
4139         ajStrAssignC(OEnv, "AE");
4140     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'C'))
4141         ajStrAssignC(OEnv, "AF");
4142     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'H'))
4143         ajStrAssignC(OEnv, "AG");
4144     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'S'))
4145         ajStrAssignC(OEnv, "AH");
4146     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'C'))
4147         ajStrAssignC(OEnv, "AI");
4148     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'H'))
4149         ajStrAssignC(OEnv, "AJ");
4150     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'S'))
4151         ajStrAssignC(OEnv, "AK");
4152     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'C'))
4153         ajStrAssignC(OEnv, "AL");
4154     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'H'))
4155         ajStrAssignC(OEnv, "AM");
4156     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'S'))
4157         ajStrAssignC(OEnv, "AN");
4158     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'C'))
4159         ajStrAssignC(OEnv, "AO");
4160     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'H'))
4161         ajStrAssignC(OEnv, "AP");
4162     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'S'))
4163         ajStrAssignC(OEnv, "AQ");
4164     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'C'))
4165         ajStrAssignC(OEnv, "AR");
4166     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'H'))
4167         ajStrAssignC(OEnv, "AS");
4168     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'S'))
4169         ajStrAssignC(OEnv, "AT");
4170     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'C'))
4171         ajStrAssignC(OEnv, "AU");
4172     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'H'))
4173         ajStrAssignC(OEnv, "AV");
4174     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'S'))
4175         ajStrAssignC(OEnv, "AW");
4176     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'C'))
4177         ajStrAssignC(OEnv, "AX");
4178     else
4179     {
4180         ajStrSetClear(OEnv);
4181         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
4182 
4183         ajStrDel(&BEnv);
4184 
4185         return 0;
4186     }
4187 
4188     ajStrDel(&BEnv);
4189 
4190     return 24;
4191 }
4192 
4193 
4194 
4195 
4196 /* @func ajResidueEnv4 ********************************************************
4197 **
4198 ** Assigns environment based only of side chain accessibility and secondary
4199 ** structure.  Assigns environment of "*" as default.
4200 **
4201 ** @param [r] residue [const AjPResidue] AJAX Residue
4202 ** @param [r] SEnv [char] Secondary structure environment code
4203 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
4204 ** @param  [w] flog [AjPFile] Log file
4205 ** @return [ajint] Number of environments
4206 **
4207 ** @release 3.0.0
4208 ** @@
4209 ******************************************************************************/
4210 
ajResidueEnv4(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)4211 ajint ajResidueEnv4(const AjPResidue residue, char SEnv, AjPStr *OEnv,
4212                     AjPFile flog)
4213 {
4214     ajStrSetClear(OEnv);
4215 
4216     if (SEnv == '\0')
4217     {
4218         ajStrSetClear(OEnv);
4219 
4220         return 0;
4221     }
4222 
4223     if ((residue->side_rel <= 5) && (SEnv == 'H'))
4224         ajStrAssignC(OEnv, "AA");
4225     else if ((residue->side_rel <= 5) && (SEnv == 'S'))
4226         ajStrAssignC(OEnv, "AB");
4227     else if ((residue->side_rel <= 5) && (SEnv == 'C'))
4228         ajStrAssignC(OEnv, "AC");
4229     else if ((residue->side_rel > 5) &&
4230              (residue->side_rel <= 25) && (SEnv == 'H'))
4231         ajStrAssignC(OEnv, "AD");
4232     else if ((residue->side_rel > 5) &&
4233              (residue->side_rel <= 25) && (SEnv == 'S'))
4234         ajStrAssignC(OEnv, "AE");
4235     else if ((residue->side_rel > 5) &&
4236              (residue->side_rel <= 25) && (SEnv == 'C'))
4237         ajStrAssignC(OEnv, "AF");
4238     else if ((residue->side_rel > 25) && (SEnv == 'H'))
4239         ajStrAssignC(OEnv, "AG");
4240     else if ((residue->side_rel > 25) && (SEnv == 'S'))
4241         ajStrAssignC(OEnv, "AH");
4242     else if ((residue->side_rel > 25) && (SEnv == 'C'))
4243         ajStrAssignC(OEnv, "AI");
4244     else
4245     {
4246         ajStrSetClear(OEnv);
4247         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
4248 
4249         return 0;
4250     }
4251 
4252     return 9;
4253 
4254 }
4255 
4256 
4257 
4258 
4259 /* @func ajResidueEnv5 ********************************************************
4260 ** Assigns environment based on side chain accessibility and secondary
4261 ** structure.  Assigns environment of "*" as default.
4262 ** @param [r] residue [const AjPResidue] AJAX Residue
4263 ** @param [r] SEnv [char]          Secondary structure environment code
4264 ** @param [w] OEnv [AjPStr*]       Character for the overall environment class
4265 ** @param  [w] flog [AjPFile] Log file
4266 ** @return [ajint] Number of environments
4267 **
4268 ** @release 3.0.0
4269 ** @@
4270 ******************************************************************************/
4271 
ajResidueEnv5(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)4272 ajint ajResidueEnv5(const AjPResidue residue, char SEnv, AjPStr *OEnv,
4273                     AjPFile flog)
4274 {
4275     float BLimit = 5.0F;        /* Upper limit for the relative solvent
4276                                  * accessible area for a buried residue */
4277     float PBLimit = 25.0F;      /* Upper limit for the relative solvent
4278                                  * accessible area for a Partially buried
4279                                  * residue */
4280 
4281     float PolLimit1 = 10.0F;
4282     float PolLimit2 = 30.0F;
4283     float PolLimit3 = 50.0F;
4284     float PolLimit4 = 80.0F;
4285 
4286     AjPStr BEnv = NULL;
4287 
4288     if (!residue)
4289     {
4290         ajWarn("No residue to ajResidueEnv");
4291 
4292         return 0;
4293     }
4294 
4295     ajStrSetClear(OEnv);
4296     BEnv = ajStrNew();
4297 
4298     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
4299                 residue->Id1, residue->Idx, residue->eType,
4300                 residue->side_rel, residue->pol_rel);
4301 
4302     /* Assign the basic classes */
4303 
4304     /* Buried */
4305     if (residue->side_rel <= BLimit)
4306         ajStrAssignC(&BEnv, "B");
4307     /* partially buried, hydrophobic */
4308     else if ((residue->side_rel > BLimit) &&
4309              (residue->side_rel <= PBLimit) &&
4310              (residue->pol_rel <= PolLimit1))
4311         ajStrAssignC(&BEnv, "P1");
4312     /* partially buried, moderately polar */
4313     else if ((residue->side_rel > BLimit) &&
4314              (residue->side_rel <= PBLimit) &&
4315              (residue->pol_rel > PolLimit1) &&
4316              (residue->pol_rel <= PolLimit2))
4317         ajStrAssignC(&BEnv, "P2");
4318     else if ((residue->side_rel > BLimit) &&
4319              (residue->side_rel <= PBLimit) &&
4320              (residue->pol_rel > PolLimit2) &&
4321              (residue->pol_rel <= PolLimit3))
4322         ajStrAssignC(&BEnv, "P3");
4323     else if ((residue->side_rel > BLimit) &&
4324              (residue->side_rel <= PBLimit) &&
4325              (residue->pol_rel > PolLimit3) &&
4326              (residue->pol_rel <= PolLimit4))
4327         ajStrAssignC(&BEnv, "P4");
4328     /* partially buried, polar */
4329     else if ((residue->side_rel > BLimit) &&
4330              (residue->side_rel <= PBLimit) &&
4331              (residue->pol_rel > PolLimit4))
4332         ajStrAssignC(&BEnv, "P5");
4333     /* Exposed, moderately Polar */
4334     else if ((residue->side_rel > PBLimit) &&
4335              (residue->pol_rel <= PolLimit3))
4336         ajStrAssignC(&BEnv, "E1");
4337     /* Exposed, Polar */
4338     else if ((residue->side_rel > PBLimit) &&
4339              (residue->pol_rel > PolLimit3))
4340         ajStrAssignC(&BEnv, "E2");
4341     else
4342     {
4343         ajStrSetClear(OEnv);
4344         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
4345 
4346         ajStrDel(&BEnv);
4347 
4348         return 0;
4349     }
4350 
4351     /* Assign overall environment class */
4352     if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'H'))
4353         ajStrAssignC(OEnv, "AA");
4354     else if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'S'))
4355         ajStrAssignC(OEnv, "AB");
4356     else if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'C'))
4357         ajStrAssignC(OEnv, "AC");
4358     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'H'))
4359         ajStrAssignC(OEnv, "AD");
4360     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'S'))
4361         ajStrAssignC(OEnv, "AE");
4362     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'C'))
4363         ajStrAssignC(OEnv, "AF");
4364     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'H'))
4365         ajStrAssignC(OEnv, "AG");
4366     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'S'))
4367         ajStrAssignC(OEnv, "AH");
4368     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'C'))
4369         ajStrAssignC(OEnv, "AI");
4370     else if ((ajStrMatchC(BEnv, "P3")) && (SEnv == 'H'))
4371         ajStrAssignC(OEnv, "AJ");
4372     else if ((ajStrMatchC(BEnv, "P3")) && (SEnv == 'S'))
4373         ajStrAssignC(OEnv, "AK");
4374     else if ((ajStrMatchC(BEnv, "P3")) && (SEnv == 'C'))
4375         ajStrAssignC(OEnv, "AL");
4376     else if ((ajStrMatchC(BEnv, "P4")) && (SEnv == 'H'))
4377         ajStrAssignC(OEnv, "AM");
4378     else if ((ajStrMatchC(BEnv, "P4")) && (SEnv == 'S'))
4379         ajStrAssignC(OEnv, "AN");
4380     else if ((ajStrMatchC(BEnv, "P4")) && (SEnv == 'C'))
4381         ajStrAssignC(OEnv, "AO");
4382     else if ((ajStrMatchC(BEnv, "P5")) && (SEnv == 'H'))
4383         ajStrAssignC(OEnv, "AP");
4384     else if ((ajStrMatchC(BEnv, "P5")) && (SEnv == 'S'))
4385         ajStrAssignC(OEnv, "AQ");
4386     else if ((ajStrMatchC(BEnv, "P5")) && (SEnv == 'C'))
4387         ajStrAssignC(OEnv, "AR");
4388     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'H'))
4389         ajStrAssignC(OEnv, "AS");
4390     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'S'))
4391         ajStrAssignC(OEnv, "AT");
4392     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'C'))
4393         ajStrAssignC(OEnv, "AU");
4394     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'H'))
4395         ajStrAssignC(OEnv, "AV");
4396     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'S'))
4397         ajStrAssignC(OEnv, "AW");
4398     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'C'))
4399         ajStrAssignC(OEnv, "AX");
4400     else
4401     {
4402         ajStrSetClear(OEnv);
4403         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
4404 
4405         ajStrDel(&BEnv);
4406         return 0;
4407     }
4408 
4409     ajStrDel(&BEnv);
4410 
4411     return 24;
4412 }
4413 
4414 
4415 
4416 
4417 /* @func ajResidueEnv6 ********************************************************
4418 **
4419 ** Assigns environment based on side chain accessibility and secondary
4420 ** structure.  Assigns environment of "*" as default.
4421 **
4422 ** @param [r] residue [const AjPResidue] AJAX Residue
4423 ** @param [r] SEnv [char] Secondary structure environment code
4424 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
4425 ** @param  [w] flog [AjPFile] Log file
4426 ** @return [ajint] Number of environments
4427 **
4428 ** @release 3.0.0
4429 ** @@
4430 ******************************************************************************/
4431 
ajResidueEnv6(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)4432 ajint ajResidueEnv6(const AjPResidue residue, char SEnv, AjPStr *OEnv,
4433                     AjPFile flog)
4434 {
4435     float BLimit = 5.0F;        /* Upper limit for the relative solvent
4436                                  * accessible area for a buried residue */
4437     float PBLimit = 25.0F;      /* Upper limit for the relative solvent
4438                                  * accessible area for a Partially buried
4439                                  * residue */
4440 
4441     float PolLimit1 = 10.0F;
4442     float PolLimit2 = 30.0F;
4443     float PolLimit3 = 50.0F;
4444     float PolLimit4 = 80.0F;
4445 
4446     AjPStr BEnv = NULL;
4447 
4448     if (!residue)
4449     {
4450         ajWarn("No residue to ajResidueEnv");
4451 
4452         return 0;
4453     }
4454 
4455     ajStrSetClear(OEnv);
4456     BEnv = ajStrNew();
4457 
4458     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
4459                 residue->Id1, residue->Idx, residue->eType,
4460                 residue->side_rel, residue->pol_rel);
4461 
4462     /* Assign the basic classes */
4463 
4464     /* Buried */
4465     if (residue->side_rel <= BLimit)
4466         ajStrAssignC(&BEnv, "B");
4467     /* Partially buried, hydrophobic */
4468     else if ((residue->side_rel > BLimit) &&
4469              (residue->side_rel <= PBLimit) &&
4470              (residue->pol_rel <= PolLimit3))
4471         ajStrAssignC(&BEnv, "P1");
4472     /* Partially buried, Polar */
4473     else if ((residue->side_rel > BLimit) &&
4474              (residue->side_rel <= PBLimit) &&
4475              (residue->pol_rel > PolLimit3))
4476         ajStrAssignC(&BEnv, "P2");
4477     /* partially buried, hydrophobic */
4478     else if ((residue->side_rel > PBLimit) &&
4479              (residue->pol_rel <= PolLimit1))
4480         ajStrAssignC(&BEnv, "E1");
4481     /* partially buried, moderately polar */
4482     else if ((residue->side_rel > PBLimit) &&
4483              (residue->pol_rel > PolLimit1) &&
4484              (residue->pol_rel <= PolLimit2))
4485         ajStrAssignC(&BEnv, "E2");
4486     else if ((residue->side_rel > PBLimit) &&
4487              (residue->pol_rel > PolLimit2) &&
4488              (residue->pol_rel <= PolLimit3))
4489         ajStrAssignC(&BEnv, "E3");
4490     else if ((residue->side_rel > PBLimit) &&
4491              (residue->pol_rel > PolLimit3) &&
4492              (residue->pol_rel <= PolLimit4))
4493         ajStrAssignC(&BEnv, "E4");
4494     /* partially buried, polar */
4495     else if ((residue->side_rel > PBLimit) &&
4496              (residue->pol_rel > PolLimit4))
4497         ajStrAssignC(&BEnv, "E5");
4498     else
4499     {
4500         ajStrSetClear(OEnv);
4501         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
4502         ajStrDel(&BEnv);
4503 
4504         return 0;
4505     }
4506 
4507     /* Assign overall environment class */
4508     if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'H'))
4509         ajStrAssignC(OEnv, "AA");
4510     else if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'S'))
4511         ajStrAssignC(OEnv, "AB");
4512     else if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'C'))
4513         ajStrAssignC(OEnv, "AC");
4514     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'H'))
4515         ajStrAssignC(OEnv, "AD");
4516     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'S'))
4517         ajStrAssignC(OEnv, "AE");
4518     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'C'))
4519         ajStrAssignC(OEnv, "AF");
4520     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'H'))
4521         ajStrAssignC(OEnv, "AG");
4522     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'S'))
4523         ajStrAssignC(OEnv, "AH");
4524     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'C'))
4525         ajStrAssignC(OEnv, "AI");
4526     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'H'))
4527         ajStrAssignC(OEnv, "AJ");
4528     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'S'))
4529         ajStrAssignC(OEnv, "AK");
4530     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'C'))
4531         ajStrAssignC(OEnv, "AL");
4532     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'H'))
4533         ajStrAssignC(OEnv, "AM");
4534     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'S'))
4535         ajStrAssignC(OEnv, "AN");
4536     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'C'))
4537         ajStrAssignC(OEnv, "AO");
4538     else if ((ajStrMatchC(BEnv, "E3")) && (SEnv == 'H'))
4539         ajStrAssignC(OEnv, "AP");
4540     else if ((ajStrMatchC(BEnv, "E3")) && (SEnv == 'S'))
4541         ajStrAssignC(OEnv, "AQ");
4542     else if ((ajStrMatchC(BEnv, "E3")) && (SEnv == 'C'))
4543         ajStrAssignC(OEnv, "AR");
4544     else if ((ajStrMatchC(BEnv, "E4")) && (SEnv == 'H'))
4545         ajStrAssignC(OEnv, "AS");
4546     else if ((ajStrMatchC(BEnv, "E4")) && (SEnv == 'S'))
4547         ajStrAssignC(OEnv, "AT");
4548     else if ((ajStrMatchC(BEnv, "E4")) && (SEnv == 'C'))
4549         ajStrAssignC(OEnv, "AU");
4550     else if ((ajStrMatchC(BEnv, "E5")) && (SEnv == 'H'))
4551         ajStrAssignC(OEnv, "AV");
4552     else if ((ajStrMatchC(BEnv, "E5")) && (SEnv == 'S'))
4553         ajStrAssignC(OEnv, "AW");
4554     else if ((ajStrMatchC(BEnv, "E5")) && (SEnv == 'C'))
4555         ajStrAssignC(OEnv, "AX");
4556     else
4557     {
4558         ajStrSetClear(OEnv);
4559         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
4560         ajStrDel(&BEnv);
4561 
4562         return 0;
4563     }
4564 
4565     ajStrDel(&BEnv);
4566 
4567     return 24;
4568 }
4569 
4570 
4571 
4572 
4573 /* @func ajResidueEnv7 ********************************************************
4574 **
4575 ** Assigns environment based on side chain accessibility and secondary
4576 ** structure.  Assigns environment of "*" as default.
4577 **
4578 ** @param [r] residue [const AjPResidue] AJAX Residue
4579 ** @param [r] SEnv [char] Secondary structure environment code
4580 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
4581 ** @param  [w] flog [AjPFile] Log file
4582 ** @return [ajint] Number of environments
4583 **
4584 ** @release 3.0.0
4585 ** @@
4586 ******************************************************************************/
4587 
ajResidueEnv7(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)4588 ajint ajResidueEnv7(const AjPResidue residue, char SEnv, AjPStr *OEnv,
4589                     AjPFile flog)
4590 {
4591     float BLimit = 5.0F;        /* Upper limit for the relative solvent
4592                                  * accessible area for a buried residue */
4593     float PBLimit = 25.0F;      /* Upper limit for the relative solvent
4594                                  * accessible area for a Partially buried
4595                                  * residue */
4596 
4597     float PolLimit1 = 10.0F;
4598     float PolLimit2 = 50.0F;
4599     float PolLimit3 = 90.0F;
4600 
4601     AjPStr BEnv = NULL;
4602 
4603     if (!residue)
4604     {
4605         ajWarn("No residue to ajResidueEnv");
4606         ajStrDel(&BEnv);
4607 
4608         return 0;
4609     }
4610 
4611     ajStrSetClear(OEnv);
4612     BEnv = ajStrNew();
4613 
4614     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
4615                 residue->Id1, residue->Idx, residue->eType,
4616                 residue->side_rel, residue->pol_rel);
4617 
4618     /* Assign the basic classes */
4619 
4620     /* Buried */
4621     if ((residue->side_rel <= BLimit) &&
4622         (residue->pol_rel <= PolLimit1))
4623         ajStrAssignC(&BEnv, "B1");
4624     else if ((residue->side_rel <= BLimit) &&
4625              (residue->pol_rel > PolLimit1) &&
4626              (residue->pol_rel <= PolLimit3))
4627         ajStrAssignC(&BEnv, "B2");
4628     else if ((residue->side_rel <= BLimit) &&
4629              (residue->pol_rel > PolLimit3))
4630         ajStrAssignC(&BEnv, "B3");
4631     else if ((residue->side_rel > BLimit) &&
4632              (residue->side_rel <= PBLimit))
4633         ajStrAssignC(&BEnv, "P");
4634     else if ((residue->side_rel > PBLimit) &&
4635              (residue->pol_rel <= PolLimit1))
4636         ajStrAssignC(&BEnv, "E1");
4637     else if ((residue->side_rel > PBLimit) &&
4638              (residue->pol_rel > PolLimit1) &&
4639              (residue->pol_rel <= PolLimit2))
4640         ajStrAssignC(&BEnv, "E2");
4641     else if ((residue->side_rel > PBLimit) &&
4642              (residue->pol_rel > PolLimit2) &&
4643              (residue->pol_rel <= PolLimit3))
4644         ajStrAssignC(&BEnv, "E3");
4645     else if ((residue->side_rel > PBLimit) && (residue->pol_rel > PolLimit3))
4646         ajStrAssignC(&BEnv, "E4");
4647     else
4648     {
4649         ajStrSetClear(OEnv);
4650         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
4651 
4652         ajStrDel(&BEnv);
4653 
4654         return 0;
4655     }
4656 
4657     /* Assign overall environment class */
4658     if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'H'))
4659         ajStrAssignC(OEnv, "AA");
4660     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'S'))
4661         ajStrAssignC(OEnv, "AB");
4662     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'C'))
4663         ajStrAssignC(OEnv, "AC");
4664     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'H'))
4665         ajStrAssignC(OEnv, "AD");
4666     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'S'))
4667         ajStrAssignC(OEnv, "AE");
4668     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'C'))
4669         ajStrAssignC(OEnv, "AF");
4670     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'H'))
4671         ajStrAssignC(OEnv, "AG");
4672     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'S'))
4673         ajStrAssignC(OEnv, "AH");
4674     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'C'))
4675         ajStrAssignC(OEnv, "AI");
4676     else if ((ajStrMatchC(BEnv, "P")) && (SEnv == 'H'))
4677         ajStrAssignC(OEnv, "AJ");
4678     else if ((ajStrMatchC(BEnv, "P")) && (SEnv == 'S'))
4679         ajStrAssignC(OEnv, "AK");
4680     else if ((ajStrMatchC(BEnv, "P")) && (SEnv == 'C'))
4681         ajStrAssignC(OEnv, "AL");
4682     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'H'))
4683         ajStrAssignC(OEnv, "AM");
4684     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'S'))
4685         ajStrAssignC(OEnv, "AN");
4686     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'C'))
4687         ajStrAssignC(OEnv, "AO");
4688     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'H'))
4689         ajStrAssignC(OEnv, "AP");
4690     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'S'))
4691         ajStrAssignC(OEnv, "AQ");
4692     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'C'))
4693         ajStrAssignC(OEnv, "AR");
4694     else if ((ajStrMatchC(BEnv, "E3")) && (SEnv == 'H'))
4695         ajStrAssignC(OEnv, "AS");
4696     else if ((ajStrMatchC(BEnv, "E3")) && (SEnv == 'S'))
4697         ajStrAssignC(OEnv, "AT");
4698     else if ((ajStrMatchC(BEnv, "E3")) && (SEnv == 'C'))
4699         ajStrAssignC(OEnv, "AU");
4700     else if ((ajStrMatchC(BEnv, "E4")) && (SEnv == 'H'))
4701         ajStrAssignC(OEnv, "AV");
4702     else if ((ajStrMatchC(BEnv, "E4")) && (SEnv == 'S'))
4703         ajStrAssignC(OEnv, "AW");
4704     else if ((ajStrMatchC(BEnv, "E4")) && (SEnv == 'C'))
4705         ajStrAssignC(OEnv, "AX");
4706     else
4707     {
4708         ajStrSetClear(OEnv);
4709         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
4710         ajStrDel(&BEnv);
4711 
4712         return 0;
4713     }
4714 
4715     ajStrDel(&BEnv);
4716 
4717     return 24;
4718 }
4719 
4720 
4721 
4722 
4723 /* @func ajResidueEnv8 ********************************************************
4724 **
4725 ** Assigns environment based only of side chain accessibility and secondary
4726 ** structure.  Assigns environment of "*" as default.
4727 **
4728 ** @param [r] residue [const AjPResidue] AJAX Residue
4729 ** @param [r] SEnv [char] Secondary structure environment code
4730 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
4731 ** @param  [w] flog [AjPFile] Log file
4732 ** @return [ajint] Number of environments
4733 **
4734 ** @release 3.0.0
4735 ** @@
4736 ******************************************************************************/
4737 
ajResidueEnv8(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)4738 ajint ajResidueEnv8(const AjPResidue residue, char SEnv, AjPStr *OEnv,
4739                     AjPFile flog)
4740 {
4741     ajStrSetClear(OEnv);
4742 
4743     if (SEnv == '\0')
4744     {
4745         ajStrSetClear(OEnv);
4746 
4747         return 0;
4748     }
4749 
4750     if ((residue->pol_rel <= 15) && (SEnv == 'H'))
4751         ajStrAssignC(OEnv, "AA");
4752     else if ((residue->pol_rel <= 15) && (SEnv == 'S'))
4753         ajStrAssignC(OEnv, "AB");
4754     else if ((residue->pol_rel <= 15) && (SEnv == 'C'))
4755         ajStrAssignC(OEnv, "AC");
4756     else if ((residue->pol_rel > 15) && (residue->pol_rel <= 30) && (SEnv == 'H'))
4757         ajStrAssignC(OEnv, "AD");
4758     else if ((residue->pol_rel > 15) && (residue->pol_rel <= 30) && (SEnv == 'S'))
4759         ajStrAssignC(OEnv, "AE");
4760     else if ((residue->pol_rel > 15) && (residue->pol_rel <= 30) && (SEnv == 'C'))
4761         ajStrAssignC(OEnv, "AF");
4762     else if ((residue->pol_rel > 30) && (residue->pol_rel <= 45) && (SEnv == 'H'))
4763         ajStrAssignC(OEnv, "AG");
4764     else if ((residue->pol_rel > 30) && (residue->pol_rel <= 45) && (SEnv == 'S'))
4765         ajStrAssignC(OEnv, "AH");
4766     else if ((residue->pol_rel > 30) && (residue->pol_rel <= 45) && (SEnv == 'C'))
4767         ajStrAssignC(OEnv, "AI");
4768     else if ((residue->pol_rel > 45) && (residue->pol_rel <= 60) && (SEnv == 'H'))
4769         ajStrAssignC(OEnv, "AJ");
4770     else if ((residue->pol_rel > 45) && (residue->pol_rel <= 60) && (SEnv == 'S'))
4771         ajStrAssignC(OEnv, "AK");
4772     else if ((residue->pol_rel > 45) && (residue->pol_rel <= 60) && (SEnv == 'C'))
4773         ajStrAssignC(OEnv, "AL");
4774     else if ((residue->pol_rel > 60) && (residue->pol_rel <= 75) && (SEnv == 'H'))
4775         ajStrAssignC(OEnv, "AM");
4776     else if ((residue->pol_rel > 60) && (residue->pol_rel <= 75) && (SEnv == 'S'))
4777         ajStrAssignC(OEnv, "AN");
4778     else if ((residue->pol_rel > 60) && (residue->pol_rel <= 75) && (SEnv == 'C'))
4779         ajStrAssignC(OEnv, "AO");
4780     else if ((residue->pol_rel > 75) && (residue->pol_rel <= 90) && (SEnv == 'H'))
4781         ajStrAssignC(OEnv, "AP");
4782     else if ((residue->pol_rel > 75) && (residue->pol_rel <= 90) && (SEnv == 'S'))
4783         ajStrAssignC(OEnv, "AQ");
4784     else if ((residue->pol_rel > 75) && (residue->pol_rel <= 90) && (SEnv == 'C'))
4785         ajStrAssignC(OEnv, "AR");
4786     else if ((residue->pol_rel > 90) && (SEnv == 'H'))
4787         ajStrAssignC(OEnv, "AS");
4788     else if ((residue->pol_rel > 90) && (SEnv == 'S'))
4789         ajStrAssignC(OEnv, "AT");
4790     else if ((residue->pol_rel > 90) && (SEnv == 'C'))
4791         ajStrAssignC(OEnv, "AU");
4792     else
4793     {
4794         ajStrSetClear(OEnv);
4795         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
4796 
4797         return 0;
4798     }
4799 
4800     return 21;
4801 }
4802 
4803 
4804 
4805 
4806 /* @func ajResidueEnv9 ********************************************************
4807 **
4808 ** Assigns environment based only of side chain accessibility and secondary
4809 ** structure.  Assigns environment of "*" as default.
4810 **
4811 ** @param [r] residue [const AjPResidue] AJAX Residue
4812 ** @param [r] SEnv [char] Secondary structure environment code
4813 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
4814 ** @param  [w] flog [AjPFile] Log file
4815 ** @return [ajint] Number of environments
4816 **
4817 ** @release 3.0.0
4818 ** @@
4819 ******************************************************************************/
4820 
ajResidueEnv9(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)4821 ajint ajResidueEnv9(const AjPResidue residue, char SEnv, AjPStr *OEnv,
4822                     AjPFile flog)
4823 {
4824     ajStrSetClear(OEnv);
4825 
4826     if (SEnv == '\0')
4827     {
4828         ajStrSetClear(OEnv);
4829 
4830         return 0;
4831     }
4832 
4833     if ((residue->pol_rel <= 5) && (SEnv == 'H'))
4834         ajStrAssignC(OEnv, "AA");
4835     else if ((residue->pol_rel <= 5) && (SEnv == 'S'))
4836         ajStrAssignC(OEnv, "AB");
4837     else if ((residue->pol_rel <= 5) && (SEnv == 'C'))
4838         ajStrAssignC(OEnv, "AC");
4839     else if ((residue->pol_rel > 5) && (residue->pol_rel <= 25) && (SEnv == 'H'))
4840         ajStrAssignC(OEnv, "AD");
4841     else if ((residue->pol_rel > 5) && (residue->pol_rel <= 25) && (SEnv == 'S'))
4842         ajStrAssignC(OEnv, "AE");
4843     else if ((residue->pol_rel > 5) && (residue->pol_rel <= 25) && (SEnv == 'C'))
4844         ajStrAssignC(OEnv, "AF");
4845     else if ((residue->pol_rel > 25) && (SEnv == 'H'))
4846         ajStrAssignC(OEnv, "AG");
4847     else if ((residue->pol_rel > 25) && (SEnv == 'S'))
4848         ajStrAssignC(OEnv, "AH");
4849     else if ((residue->pol_rel > 25) && (SEnv == 'C'))
4850         ajStrAssignC(OEnv, "AI");
4851     else
4852     {
4853         ajStrSetClear(OEnv);
4854         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
4855 
4856         return 0;
4857     }
4858 
4859     return 9;
4860 }
4861 
4862 
4863 
4864 
4865 /* @func ajResidueEnv10 *******************************************************
4866 **
4867 ** Assigns environment based on side chain accessibility and secondary
4868 ** structure.  Assigns environment of "*" as default.
4869 **
4870 ** @param [r] residue [const AjPResidue] AJAX Residue
4871 ** @param [r] SEnv [char] Secondary structure environment code
4872 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
4873 ** @param  [w] flog [AjPFile] Log file
4874 ** @return [ajint] Number of environments
4875 **
4876 ** @release 3.0.0
4877 ** @@
4878 ******************************************************************************/
4879 
ajResidueEnv10(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)4880 ajint ajResidueEnv10(const AjPResidue residue, char SEnv, AjPStr *OEnv,
4881                      AjPFile flog)
4882 {
4883     float BLimit = 5.0F;        /* Upper limit for the relative solvent
4884                                  * accessible area for a buried residue */
4885     float PBLimit = 25.0F;      /* Upper limit for the relative solvent
4886                                  * accessible area for a Partially buried
4887                                  * residue */
4888 
4889     float HLimit = 5.0F;        /* Upper limit for the fraction polar measure
4890                                  * of a Hydrophobic residue */
4891     float MPLimit = 25.0F;      /* Upper limit for the fraction polar measure
4892                                  * of a Moderately polar residue */
4893 
4894     AjPStr BEnv = NULL;
4895 
4896     if (!residue)
4897     {
4898         ajWarn("No residue to ajResidueEnv");
4899 
4900         return 0;
4901     }
4902 
4903     ajStrSetClear(OEnv);
4904     BEnv = ajStrNew();
4905 
4906     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
4907                 residue->Id1, residue->Idx, residue->eType,
4908                 residue->side_rel, residue->pol_rel);
4909 
4910     /* Assign the basic classes */
4911 
4912     /* Buried, Hydrophobic */
4913     if ((residue->side_rel <= BLimit) &&
4914         (residue->pol_rel <= HLimit))
4915         ajStrAssignC(&BEnv, "B1");
4916     /* buried, moderately polar */
4917     else if ((residue->side_rel <= BLimit) &&
4918              (residue->pol_rel > HLimit) &&
4919              (residue->pol_rel <= MPLimit))
4920         ajStrAssignC(&BEnv, "B2");
4921     /* buried, polar */
4922     else if ((residue->side_rel <= BLimit) &&
4923              (residue->pol_rel > MPLimit))
4924         ajStrAssignC(&BEnv, "B3");
4925     /* Partially buried, moderately hydrophobic */
4926     else if ((residue->side_rel > BLimit) &&
4927              (residue->side_rel <= PBLimit) &&
4928              (residue->pol_rel <= HLimit))
4929         ajStrAssignC(&BEnv, "P1");
4930     /* Partially buried, moderately polar */
4931     else if ((residue->side_rel > BLimit) &&
4932              (residue->side_rel <= PBLimit) &&
4933              (residue->pol_rel > HLimit) &&
4934              (residue->pol_rel <= MPLimit))
4935         ajStrAssignC(&BEnv, "P2");
4936     /* Partially buried, polar */
4937     else if ((residue->side_rel > BLimit) &&
4938              (residue->side_rel <= PBLimit) && (residue->pol_rel > MPLimit))
4939         ajStrAssignC(&BEnv, "P3");
4940     /* Exposed, moderately polar */
4941     else if ((residue->side_rel > PBLimit) &&
4942              (residue->pol_rel <= MPLimit))
4943         ajStrAssignC(&BEnv, "E1");
4944     /* Exposed, polar */
4945     else if ((residue->side_rel > PBLimit) &&
4946              (residue->pol_rel > MPLimit))
4947         ajStrAssignC(&BEnv, "E2");
4948     else
4949     {
4950         ajStrSetClear(OEnv);
4951         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
4952 
4953         ajStrDel(&BEnv);
4954 
4955         return 0;
4956     }
4957 
4958     /* Assign overall environment class */
4959     if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'H'))
4960         ajStrAssignC(OEnv, "AA");
4961     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'S'))
4962         ajStrAssignC(OEnv, "AB");
4963     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'C'))
4964         ajStrAssignC(OEnv, "AC");
4965     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'H'))
4966         ajStrAssignC(OEnv, "AD");
4967     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'S'))
4968         ajStrAssignC(OEnv, "AE");
4969     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'C'))
4970         ajStrAssignC(OEnv, "AF");
4971     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'H'))
4972         ajStrAssignC(OEnv, "AG");
4973     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'S'))
4974         ajStrAssignC(OEnv, "AH");
4975     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'C'))
4976         ajStrAssignC(OEnv, "AI");
4977     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'H'))
4978         ajStrAssignC(OEnv, "AJ");
4979     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'S'))
4980         ajStrAssignC(OEnv, "AK");
4981     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'C'))
4982         ajStrAssignC(OEnv, "AL");
4983     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'H'))
4984         ajStrAssignC(OEnv, "AM");
4985     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'S'))
4986         ajStrAssignC(OEnv, "AN");
4987     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'C'))
4988         ajStrAssignC(OEnv, "AO");
4989     else if ((ajStrMatchC(BEnv, "P3")) && (SEnv == 'H'))
4990         ajStrAssignC(OEnv, "AP");
4991     else if ((ajStrMatchC(BEnv, "P3")) && (SEnv == 'S'))
4992         ajStrAssignC(OEnv, "AQ");
4993     else if ((ajStrMatchC(BEnv, "P3")) && (SEnv == 'C'))
4994         ajStrAssignC(OEnv, "AR");
4995     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'H'))
4996         ajStrAssignC(OEnv, "AS");
4997     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'S'))
4998         ajStrAssignC(OEnv, "AT");
4999     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'C'))
5000         ajStrAssignC(OEnv, "AU");
5001     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'H'))
5002         ajStrAssignC(OEnv, "AV");
5003     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'S'))
5004         ajStrAssignC(OEnv, "AW");
5005     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'C'))
5006         ajStrAssignC(OEnv, "AX");
5007     else
5008     {
5009         ajStrSetClear(OEnv);
5010         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
5011         ajStrDel(&BEnv);
5012 
5013         return 0;
5014     }
5015 
5016     ajStrDel(&BEnv);
5017 
5018     return 24;
5019 }
5020 
5021 
5022 
5023 
5024 /* @func ajResidueEnv11 *******************************************************
5025 **
5026 ** Assigns environment based on side chain accessibility and secondary
5027 ** structure.  Assigns environment of "*" as default.
5028 **
5029 ** @param [r] residue [const AjPResidue] AJAX Residue
5030 ** @param [r] SEnv [char] Secondary structure environment code
5031 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
5032 ** @param  [w] flog [AjPFile] Log file
5033 ** @return [ajint] Number of environments
5034 **
5035 ** @release 3.0.0
5036 ** @@
5037 ******************************************************************************/
5038 
ajResidueEnv11(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)5039 ajint ajResidueEnv11(const AjPResidue residue, char SEnv, AjPStr *OEnv,
5040                      AjPFile flog)
5041 {
5042     float BLimit = 5.0F;        /* Upper limit for the relative solvent
5043                                  * accessible area for a buried residue */
5044     float PBLimit = 25.0F;      /* Upper limit for the relative solvent
5045                                  * accessible area for a Partially buried
5046                                  * residue */
5047 
5048     float PolLimit1 = 10.0F;
5049     float PolLimit2 = 30.0F;
5050     float PolLimit3 = 50.0F;
5051     float PolLimit4 = 70.0F;
5052     float PolLimit5 = 90.0F;
5053 
5054     AjPStr BEnv = NULL;
5055 
5056     if (!residue)
5057     {
5058         ajWarn("No residue to ajResidueEnv");
5059 
5060         return 0;
5061     }
5062 
5063     ajStrSetClear(OEnv);
5064     BEnv = ajStrNew();
5065 
5066     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
5067                 residue->Id1, residue->Idx, residue->eType,
5068                 residue->side_rel, residue->pol_rel);
5069 
5070     /* Assign the basic classes */
5071 
5072     if ((residue->side_rel <= BLimit) &&
5073         (residue->pol_rel <= PolLimit1))
5074         ajStrAssignC(&BEnv, "B1");
5075     else if ((residue->side_rel <= BLimit) &&
5076              (residue->pol_rel > PolLimit1) &&
5077              (residue->pol_rel <= PolLimit2))
5078         ajStrAssignC(&BEnv, "B2");
5079     else if ((residue->side_rel <= BLimit) &&
5080              (residue->pol_rel > PolLimit2) &&
5081              (residue->pol_rel <= PolLimit3))
5082         ajStrAssignC(&BEnv, "B3");
5083     else if ((residue->side_rel <= BLimit) &&
5084              (residue->pol_rel > PolLimit3) &&
5085              (residue->pol_rel <= PolLimit4))
5086         ajStrAssignC(&BEnv, "B4");
5087     else if ((residue->side_rel <= BLimit) &&
5088              (residue->pol_rel > PolLimit4) &&
5089              (residue->pol_rel <= PolLimit5))
5090         ajStrAssignC(&BEnv, "B5");
5091     else if ((residue->side_rel <= BLimit) &&
5092              (residue->pol_rel > PolLimit5))
5093         ajStrAssignC(&BEnv, "B6");
5094     else if ((residue->side_rel > BLimit) &&
5095              (residue->side_rel <= PBLimit))
5096         ajStrAssignC(&BEnv, "P");
5097     else if (residue->side_rel > PBLimit)
5098         ajStrAssignC(&BEnv, "E");
5099     else
5100     {
5101         ajStrSetClear(OEnv);
5102         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
5103         ajStrDel(&BEnv);
5104 
5105         return 0;
5106     }
5107 
5108     /* Assign overall environment class */
5109     if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'H'))
5110         ajStrAssignC(OEnv, "AA");
5111     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'S'))
5112         ajStrAssignC(OEnv, "AB");
5113     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'C'))
5114         ajStrAssignC(OEnv, "AC");
5115     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'H'))
5116         ajStrAssignC(OEnv, "AD");
5117     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'S'))
5118         ajStrAssignC(OEnv, "AE");
5119     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'C'))
5120         ajStrAssignC(OEnv, "AF");
5121     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'H'))
5122         ajStrAssignC(OEnv, "AG");
5123     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'S'))
5124         ajStrAssignC(OEnv, "AH");
5125     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'C'))
5126         ajStrAssignC(OEnv, "AI");
5127     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'H'))
5128         ajStrAssignC(OEnv, "AJ");
5129     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'S'))
5130         ajStrAssignC(OEnv, "AK");
5131     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'C'))
5132         ajStrAssignC(OEnv, "AL");
5133     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'H'))
5134         ajStrAssignC(OEnv, "AM");
5135     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'S'))
5136         ajStrAssignC(OEnv, "AN");
5137     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'C'))
5138         ajStrAssignC(OEnv, "AO");
5139     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'H'))
5140         ajStrAssignC(OEnv, "AP");
5141     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'S'))
5142         ajStrAssignC(OEnv, "AQ");
5143     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'C'))
5144         ajStrAssignC(OEnv, "AR");
5145     else if ((ajStrMatchC(BEnv, "P")) && (SEnv == 'H'))
5146         ajStrAssignC(OEnv, "AS");
5147     else if ((ajStrMatchC(BEnv, "P")) && (SEnv == 'S'))
5148         ajStrAssignC(OEnv, "AT");
5149     else if ((ajStrMatchC(BEnv, "P")) && (SEnv == 'C'))
5150         ajStrAssignC(OEnv, "AU");
5151     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'H'))
5152         ajStrAssignC(OEnv, "AV");
5153     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'S'))
5154         ajStrAssignC(OEnv, "AW");
5155     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'C'))
5156         ajStrAssignC(OEnv, "AX");
5157     else
5158     {
5159         ajStrSetClear(OEnv);
5160         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
5161 
5162         ajStrDel(&BEnv);
5163         return 0;
5164     }
5165 
5166     ajStrDel(&BEnv);
5167 
5168     return 24;
5169 }
5170 
5171 
5172 
5173 
5174 /* @func ajResidueEnv12 *******************************************************
5175 **
5176 ** Assigns environment based on side chain accessibility and secondary
5177 ** structure.  Assigns environment of "*" as default.
5178 **
5179 ** @param [r] residue [const AjPResidue] AJAX Residue
5180 ** @param [r] SEnv [char] Secondary structure environment code
5181 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
5182 ** @param  [w] flog [AjPFile] Log file
5183 ** @return [ajint] Number of environments
5184 **
5185 ** @release 3.0.0
5186 ** @@
5187 ******************************************************************************/
5188 
ajResidueEnv12(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)5189 ajint ajResidueEnv12(const AjPResidue residue, char SEnv, AjPStr *OEnv,
5190                      AjPFile flog)
5191 {
5192     float BLimit = 5.0F;        /* Upper limit for the relative solvent
5193                                  * accessible area for a buried residue */
5194     float PBLimit = 25.0F;      /* Upper limit for the relative solvent
5195                                  * accessible area for a Partially buried
5196                                  * residue */
5197 
5198     float PolLimit1 = 10.0F;
5199     float PolLimit2 = 30.0F;
5200     float PolLimit3 = 50.0F;
5201     float PolLimit4 = 70.0F;
5202     float PolLimit5 = 90.0F;
5203 
5204     AjPStr BEnv = NULL;
5205 
5206     if (!residue)
5207     {
5208         ajWarn("No residue to ajResidueEnv");
5209 
5210         return 0;
5211     }
5212 
5213     ajStrSetClear(OEnv);
5214     BEnv = ajStrNew();
5215 
5216     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n", residue->Id1, residue->Idx,
5217                 residue->eType, residue->side_rel, residue->pol_rel);
5218 
5219     /* Assign the basic classes */
5220 
5221     if ((residue->side_rel <= BLimit))
5222         ajStrAssignC(&BEnv, "B");
5223     else if ((residue->side_rel > BLimit) &&
5224              (residue->side_rel <= PBLimit) &&
5225              (residue->pol_rel <= PolLimit1))
5226         ajStrAssignC(&BEnv, "P1");
5227     else if ((residue->side_rel > BLimit) &&
5228              (residue->side_rel <= PBLimit) &&
5229              (residue->pol_rel > PolLimit1) &&
5230              (residue->pol_rel <= PolLimit2))
5231         ajStrAssignC(&BEnv, "P2");
5232     else if ((residue->side_rel > BLimit) &&
5233              (residue->side_rel <= PBLimit) &&
5234              (residue->pol_rel > PolLimit2) &&
5235              (residue->pol_rel <= PolLimit3))
5236         ajStrAssignC(&BEnv, "P3");
5237     else if ((residue->side_rel > BLimit) &&
5238              (residue->side_rel <= PBLimit) &&
5239              (residue->pol_rel > PolLimit3) &&
5240              (residue->pol_rel <= PolLimit4))
5241         ajStrAssignC(&BEnv, "P4");
5242     else if ((residue->side_rel > BLimit) &&
5243              (residue->side_rel <= PBLimit) &&
5244              (residue->pol_rel > PolLimit4) &&
5245              (residue->pol_rel <= PolLimit5))
5246         ajStrAssignC(&BEnv, "P5");
5247     else if ((residue->side_rel > BLimit) &&
5248              (residue->side_rel <= PBLimit) &&
5249              (residue->pol_rel > PolLimit5))
5250         ajStrAssignC(&BEnv, "P6");
5251     else if (residue->side_rel > PBLimit)
5252         ajStrAssignC(&BEnv, "E");
5253     else
5254     {
5255         ajStrSetClear(OEnv);
5256         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
5257         ajStrDel(&BEnv);
5258 
5259         return 0;
5260     }
5261 
5262     /* Assign overall environment class */
5263     if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'H'))
5264         ajStrAssignC(OEnv, "AA");
5265     else if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'S'))
5266         ajStrAssignC(OEnv, "AB");
5267     else if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'C'))
5268         ajStrAssignC(OEnv, "AC");
5269     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'H'))
5270         ajStrAssignC(OEnv, "AD");
5271     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'S'))
5272         ajStrAssignC(OEnv, "AE");
5273     else if ((ajStrMatchC(BEnv, "P1")) && (SEnv == 'C'))
5274         ajStrAssignC(OEnv, "AF");
5275     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'H'))
5276         ajStrAssignC(OEnv, "AG");
5277     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'S'))
5278         ajStrAssignC(OEnv, "AH");
5279     else if ((ajStrMatchC(BEnv, "P2")) && (SEnv == 'C'))
5280         ajStrAssignC(OEnv, "AI");
5281     else if ((ajStrMatchC(BEnv, "P3")) && (SEnv == 'H'))
5282         ajStrAssignC(OEnv, "AJ");
5283     else if ((ajStrMatchC(BEnv, "P3")) && (SEnv == 'S'))
5284         ajStrAssignC(OEnv, "AK");
5285     else if ((ajStrMatchC(BEnv, "P3")) && (SEnv == 'C'))
5286         ajStrAssignC(OEnv, "AL");
5287     else if ((ajStrMatchC(BEnv, "P4")) && (SEnv == 'H'))
5288         ajStrAssignC(OEnv, "AM");
5289     else if ((ajStrMatchC(BEnv, "P4")) && (SEnv == 'S'))
5290         ajStrAssignC(OEnv, "AN");
5291     else if ((ajStrMatchC(BEnv, "P4")) && (SEnv == 'C'))
5292         ajStrAssignC(OEnv, "AO");
5293     else if ((ajStrMatchC(BEnv, "P5")) && (SEnv == 'H'))
5294         ajStrAssignC(OEnv, "AP");
5295     else if ((ajStrMatchC(BEnv, "P5")) && (SEnv == 'S'))
5296         ajStrAssignC(OEnv, "AQ");
5297     else if ((ajStrMatchC(BEnv, "P5")) && (SEnv == 'C'))
5298         ajStrAssignC(OEnv, "AR");
5299     else if ((ajStrMatchC(BEnv, "P6")) && (SEnv == 'H'))
5300         ajStrAssignC(OEnv, "AS");
5301     else if ((ajStrMatchC(BEnv, "P6")) && (SEnv == 'S'))
5302         ajStrAssignC(OEnv, "AT");
5303     else if ((ajStrMatchC(BEnv, "P6")) && (SEnv == 'C'))
5304         ajStrAssignC(OEnv, "AU");
5305     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'H'))
5306         ajStrAssignC(OEnv, "AV");
5307     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'S'))
5308         ajStrAssignC(OEnv, "AW");
5309     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'C'))
5310         ajStrAssignC(OEnv, "AX");
5311     else
5312     {
5313         ajStrSetClear(OEnv);
5314         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
5315         ajStrDel(&BEnv);
5316 
5317         return 0;
5318     }
5319 
5320     ajStrDel(&BEnv);
5321 
5322     return 24;
5323 }
5324 
5325 
5326 
5327 
5328 /* @func ajResidueEnv13 *******************************************************
5329 **
5330 ** Assigns environment based on side chain accessibility and secondary
5331 ** structure.  Assigns environment of "*" as default.
5332 **
5333 ** @param [r] residue [const AjPResidue] AJAX Residue
5334 ** @param [r] SEnv [char] Secondary structure environment code
5335 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
5336 ** @param  [w] flog [AjPFile] Log file
5337 ** @return [ajint] Number of environments
5338 **
5339 ** @release 3.0.0
5340 ** @@
5341 ******************************************************************************/
5342 
ajResidueEnv13(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)5343 ajint ajResidueEnv13(const AjPResidue residue, char SEnv, AjPStr *OEnv,
5344                      AjPFile flog)
5345 {
5346     float BLimit = 5.0F;        /* Upper limit for the relative solvent
5347                                  * accessible area for a buried residue */
5348     float PBLimit = 25.0F;      /* Upper limit for the relative solvent
5349                                  * accessible area for a Partially buried
5350                                  * residue */
5351 
5352     float PolLimit1 = 10.0F;
5353     float PolLimit2 = 30.0F;
5354     float PolLimit3 = 50.0F;
5355     float PolLimit4 = 70.0F;
5356     float PolLimit5 = 90.0F;
5357 
5358     AjPStr BEnv = NULL;
5359 
5360     if (!residue)
5361     {
5362         ajWarn("No residue to ajResidueEnv");
5363 
5364         return 0;
5365     }
5366 
5367     ajStrSetClear(OEnv);
5368     BEnv = ajStrNew();
5369 
5370     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
5371                 residue->Id1, residue->Idx, residue->eType,
5372                 residue->side_rel, residue->pol_rel);
5373 
5374     /* Assign the basic classes */
5375     if ((residue->side_rel <= BLimit))
5376         ajStrAssignC(&BEnv, "B");
5377     else if ((residue->side_rel > BLimit) &&
5378              (residue->side_rel <= PBLimit))
5379         ajStrAssignC(&BEnv, "P");
5380     else if ((residue->side_rel > PBLimit) &&
5381              (residue->pol_rel <= PolLimit1))
5382         ajStrAssignC(&BEnv, "E1");
5383     else if ((residue->side_rel > PBLimit) &&
5384              (residue->pol_rel > PolLimit1) &&
5385              (residue->pol_rel <= PolLimit2))
5386         ajStrAssignC(&BEnv, "E2");
5387     else if ((residue->side_rel > PBLimit) &&
5388              (residue->pol_rel > PolLimit2) &&
5389              (residue->pol_rel <= PolLimit3))
5390         ajStrAssignC(&BEnv, "E3");
5391     else if ((residue->side_rel > PBLimit) &&
5392              (residue->pol_rel > PolLimit3) &&
5393              (residue->pol_rel <= PolLimit4))
5394         ajStrAssignC(&BEnv, "E4");
5395     else if ((residue->side_rel > PBLimit) &&
5396              (residue->pol_rel > PolLimit4) &&
5397              (residue->pol_rel <= PolLimit5))
5398         ajStrAssignC(&BEnv, "E5");
5399     else if ((residue->side_rel > PBLimit) &&
5400              (residue->pol_rel > PolLimit5))
5401         ajStrAssignC(&BEnv, "E6");
5402     else
5403     {
5404         ajStrSetClear(OEnv);
5405         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
5406         ajStrDel(&BEnv);
5407 
5408         return 0;
5409     }
5410 
5411     /* Assign overall environment class */
5412     if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'H'))
5413         ajStrAssignC(OEnv, "AA");
5414     else if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'S'))
5415         ajStrAssignC(OEnv, "AB");
5416     else if ((ajStrMatchC(BEnv, "B")) && (SEnv == 'C'))
5417         ajStrAssignC(OEnv, "AC");
5418     else if ((ajStrMatchC(BEnv, "P")) && (SEnv == 'H'))
5419         ajStrAssignC(OEnv, "AD");
5420     else if ((ajStrMatchC(BEnv, "P")) && (SEnv == 'S'))
5421         ajStrAssignC(OEnv, "AE");
5422     else if ((ajStrMatchC(BEnv, "P")) && (SEnv == 'C'))
5423         ajStrAssignC(OEnv, "AF");
5424     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'H'))
5425         ajStrAssignC(OEnv, "AG");
5426     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'S'))
5427         ajStrAssignC(OEnv, "AH");
5428     else if ((ajStrMatchC(BEnv, "E1")) && (SEnv == 'C'))
5429         ajStrAssignC(OEnv, "AI");
5430     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'H'))
5431         ajStrAssignC(OEnv, "AJ");
5432     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'S'))
5433         ajStrAssignC(OEnv, "AK");
5434     else if ((ajStrMatchC(BEnv, "E2")) && (SEnv == 'C'))
5435         ajStrAssignC(OEnv, "AL");
5436     else if ((ajStrMatchC(BEnv, "E3")) && (SEnv == 'H'))
5437         ajStrAssignC(OEnv, "AM");
5438     else if ((ajStrMatchC(BEnv, "E3")) && (SEnv == 'S'))
5439         ajStrAssignC(OEnv, "AN");
5440     else if ((ajStrMatchC(BEnv, "E3")) && (SEnv == 'C'))
5441         ajStrAssignC(OEnv, "AO");
5442     else if ((ajStrMatchC(BEnv, "E4")) && (SEnv == 'H'))
5443         ajStrAssignC(OEnv, "AP");
5444     else if ((ajStrMatchC(BEnv, "E4")) && (SEnv == 'S'))
5445         ajStrAssignC(OEnv, "AQ");
5446     else if ((ajStrMatchC(BEnv, "E4")) && (SEnv == 'C'))
5447         ajStrAssignC(OEnv, "AR");
5448     else if ((ajStrMatchC(BEnv, "E5")) && (SEnv == 'H'))
5449         ajStrAssignC(OEnv, "AS");
5450     else if ((ajStrMatchC(BEnv, "E5")) && (SEnv == 'S'))
5451         ajStrAssignC(OEnv, "AT");
5452     else if ((ajStrMatchC(BEnv, "E5")) && (SEnv == 'C'))
5453         ajStrAssignC(OEnv, "AU");
5454     else if ((ajStrMatchC(BEnv, "E6")) && (SEnv == 'H'))
5455         ajStrAssignC(OEnv, "AV");
5456     else if ((ajStrMatchC(BEnv, "E6")) && (SEnv == 'S'))
5457         ajStrAssignC(OEnv, "AW");
5458     else if ((ajStrMatchC(BEnv, "E6")) && (SEnv == 'C'))
5459         ajStrAssignC(OEnv, "AX");
5460     else
5461     {
5462         ajStrSetClear(OEnv);
5463         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
5464         ajStrDel(&BEnv);
5465 
5466         return 0;
5467     }
5468 
5469     ajStrDel(&BEnv);
5470 
5471     return 24;
5472 }
5473 
5474 
5475 
5476 
5477 /* @func ajResidueEnv14 *******************************************************
5478 **
5479 ** Assigns environment based on side chain accessibility and secondary
5480 ** structure.  Assigns environment of "*" as default.
5481 **
5482 ** @param [r] residue [const AjPResidue] AJAX Residue
5483 ** @param [r] SEnv [char] Secondary structure environment code
5484 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
5485 ** @param  [w] flog [AjPFile] Log file
5486 ** @return [ajint] Number of environments
5487 **
5488 ** @release 3.0.0
5489 ** @@
5490 ******************************************************************************/
5491 
ajResidueEnv14(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)5492 ajint ajResidueEnv14(const AjPResidue residue, char SEnv, AjPStr *OEnv,
5493                      AjPFile flog)
5494 {
5495     float PBLimit = 25.0F;      /* Upper limit for the relative solvent
5496                                  * accessible area for a Partially buried
5497                                  * residue */
5498 
5499     float PolLimit1 = 5.0F;
5500     float PolLimit2 = 15.0F;
5501     float PolLimit3 = 25.0F;
5502     float PolLimit4 = 40.0F;
5503     float PolLimit5 = 60.0F;
5504     float PolLimit6 = 80.0F;
5505 
5506     AjPStr BEnv = NULL;
5507 
5508     if (!residue)
5509     {
5510         ajWarn("No residue to ajResidueEnv");
5511 
5512         return 0;
5513     }
5514 
5515     ajStrSetClear(OEnv);
5516     BEnv = ajStrNew();
5517 
5518     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
5519                 residue->Id1, residue->Idx, residue->eType,
5520                 residue->side_rel, residue->pol_rel);
5521 
5522     if ((residue->side_rel <= PBLimit) &&
5523         (residue->pol_rel <= PolLimit1))
5524         ajStrAssignC(&BEnv, "B1");
5525     else if ((residue->side_rel <= PBLimit) &&
5526              (residue->pol_rel > PolLimit1) &&
5527              (residue->pol_rel <= PolLimit2))
5528         ajStrAssignC(&BEnv, "B2");
5529     else if ((residue->side_rel <= PBLimit) &&
5530              (residue->pol_rel > PolLimit2) &&
5531              (residue->pol_rel <= PolLimit3))
5532         ajStrAssignC(&BEnv, "B3");
5533     else if ((residue->side_rel <= PBLimit) &&
5534              (residue->pol_rel > PolLimit3) &&
5535              (residue->pol_rel <= PolLimit4))
5536         ajStrAssignC(&BEnv, "B4");
5537     else if ((residue->side_rel <= PBLimit) &&
5538              (residue->pol_rel > PolLimit4) &&
5539              (residue->pol_rel <= PolLimit5))
5540         ajStrAssignC(&BEnv, "B5");
5541     else if ((residue->side_rel <= PBLimit) &&
5542              (residue->pol_rel > PolLimit5) &&
5543              (residue->pol_rel <= PolLimit6))
5544         ajStrAssignC(&BEnv, "B6");
5545     else if ((residue->side_rel <= PBLimit) &&
5546              (residue->pol_rel > PolLimit6))
5547         ajStrAssignC(&BEnv, "B7");
5548     else if ((residue->side_rel > PBLimit))
5549         ajStrAssignC(&BEnv, "E");
5550     else
5551     {
5552         ajStrSetClear(OEnv);
5553         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
5554         ajStrDel(&BEnv);
5555 
5556         return 0;
5557     }
5558 
5559     /* Assign overall environment class */
5560     if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'H'))
5561         ajStrAssignC(OEnv, "AA");
5562     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'S'))
5563         ajStrAssignC(OEnv, "AB");
5564     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'C'))
5565         ajStrAssignC(OEnv, "AC");
5566     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'H'))
5567         ajStrAssignC(OEnv, "AD");
5568     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'S'))
5569         ajStrAssignC(OEnv, "AE");
5570     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'C'))
5571         ajStrAssignC(OEnv, "AF");
5572     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'H'))
5573         ajStrAssignC(OEnv, "AG");
5574     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'S'))
5575         ajStrAssignC(OEnv, "AH");
5576     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'C'))
5577         ajStrAssignC(OEnv, "AI");
5578     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'H'))
5579         ajStrAssignC(OEnv, "AJ");
5580     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'S'))
5581         ajStrAssignC(OEnv, "AK");
5582     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'C'))
5583         ajStrAssignC(OEnv, "AL");
5584     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'H'))
5585         ajStrAssignC(OEnv, "AM");
5586     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'S'))
5587         ajStrAssignC(OEnv, "AN");
5588     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'C'))
5589         ajStrAssignC(OEnv, "AO");
5590     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'H'))
5591         ajStrAssignC(OEnv, "AP");
5592     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'S'))
5593         ajStrAssignC(OEnv, "AQ");
5594     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'C'))
5595         ajStrAssignC(OEnv, "AR");
5596     else if ((ajStrMatchC(BEnv, "B7")) && (SEnv == 'H'))
5597         ajStrAssignC(OEnv, "AS");
5598     else if ((ajStrMatchC(BEnv, "B7")) && (SEnv == 'S'))
5599         ajStrAssignC(OEnv, "AT");
5600     else if ((ajStrMatchC(BEnv, "B7")) && (SEnv == 'C'))
5601         ajStrAssignC(OEnv, "AU");
5602     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'H'))
5603         ajStrAssignC(OEnv, "AV");
5604     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'S'))
5605         ajStrAssignC(OEnv, "AW");
5606     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'C'))
5607         ajStrAssignC(OEnv, "AX");
5608     else
5609     {
5610         ajStrSetClear(OEnv);
5611         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
5612         ajStrDel(&BEnv);
5613 
5614         return 0;
5615     }
5616 
5617     ajStrDel(&BEnv);
5618 
5619     return 24;
5620 }
5621 
5622 
5623 
5624 
5625 /* @func ajResidueEnv15 *******************************************************
5626 **
5627 ** Assigns environment based on side chain accessibility and secondary
5628 ** structure.   Assigns environment of "*" as default.
5629 **
5630 ** @param [r] residue [const AjPResidue] AJAX Residue
5631 ** @param [r] SEnv [char] Secondary structure environment code
5632 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
5633 ** @param  [w] flog [AjPFile] Log file
5634 ** @return [ajint] Number of environments
5635 **
5636 ** @release 3.0.0
5637 ** @@
5638 ******************************************************************************/
5639 
ajResidueEnv15(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)5640 ajint ajResidueEnv15(const AjPResidue residue, char SEnv, AjPStr *OEnv,
5641                      AjPFile flog)
5642 {
5643     float PBLimit = 25.0F;      /* Upper limit for the relative solvent
5644                                  * accessible area for a Partially buried
5645                                  * residue */
5646 
5647     float PolLimit1 = 5.0F;
5648     float PolLimit2 = 15.0F;
5649     float PolLimit3 = 25.0F;
5650     float PolLimit4 = 35.0F;
5651     float PolLimit5 = 45.0F;
5652     float PolLimit6 = 75.0F;
5653 
5654     AjPStr BEnv = NULL;
5655 
5656     if (!residue)
5657     {
5658         ajWarn("No residue to ajResidueEnv");
5659 
5660         return 0;
5661     }
5662 
5663     ajStrSetClear(OEnv);
5664     BEnv = ajStrNew();
5665 
5666     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
5667                 residue->Id1, residue->Idx, residue->eType,
5668                 residue->side_rel, residue->pol_rel);
5669 
5670     if ((residue->side_rel <= PBLimit) && (residue->pol_rel <= PolLimit1))
5671         ajStrAssignC(&BEnv, "B1");
5672     else if ((residue->side_rel <= PBLimit) &&
5673              (residue->pol_rel > PolLimit1) &&
5674              (residue->pol_rel <= PolLimit2))
5675         ajStrAssignC(&BEnv, "B2");
5676     else if ((residue->side_rel <= PBLimit) &&
5677              (residue->pol_rel > PolLimit2) &&
5678              (residue->pol_rel <= PolLimit3))
5679         ajStrAssignC(&BEnv, "B3");
5680     else if ((residue->side_rel <= PBLimit) &&
5681              (residue->pol_rel > PolLimit3) &&
5682              (residue->pol_rel <= PolLimit4))
5683         ajStrAssignC(&BEnv, "B4");
5684     else if ((residue->side_rel <= PBLimit) &&
5685              (residue->pol_rel > PolLimit4) &&
5686              (residue->pol_rel <= PolLimit5))
5687         ajStrAssignC(&BEnv, "B5");
5688     else if ((residue->side_rel <= PBLimit) &&
5689              (residue->pol_rel > PolLimit5) &&
5690              (residue->pol_rel <= PolLimit6))
5691         ajStrAssignC(&BEnv, "B6");
5692     else if ((residue->side_rel <= PBLimit) &&
5693              (residue->pol_rel > PolLimit6))
5694         ajStrAssignC(&BEnv, "B7");
5695     else if ((residue->side_rel > PBLimit))
5696         ajStrAssignC(&BEnv, "E");
5697     else
5698     {
5699         ajStrSetClear(OEnv);
5700         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
5701         ajStrDel(&BEnv);
5702 
5703         return 0;
5704     }
5705 
5706     /* Assign overall environment class */
5707     if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'H'))
5708         ajStrAssignC(OEnv, "AA");
5709     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'S'))
5710         ajStrAssignC(OEnv, "AB");
5711     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'C'))
5712         ajStrAssignC(OEnv, "AC");
5713     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'H'))
5714         ajStrAssignC(OEnv, "AD");
5715     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'S'))
5716         ajStrAssignC(OEnv, "AE");
5717     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'C'))
5718         ajStrAssignC(OEnv, "AF");
5719     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'H'))
5720         ajStrAssignC(OEnv, "AG");
5721     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'S'))
5722         ajStrAssignC(OEnv, "AH");
5723     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'C'))
5724         ajStrAssignC(OEnv, "AI");
5725     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'H'))
5726         ajStrAssignC(OEnv, "AJ");
5727     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'S'))
5728         ajStrAssignC(OEnv, "AK");
5729     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'C'))
5730         ajStrAssignC(OEnv, "AL");
5731     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'H'))
5732         ajStrAssignC(OEnv, "AM");
5733     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'S'))
5734         ajStrAssignC(OEnv, "AN");
5735     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'C'))
5736         ajStrAssignC(OEnv, "AO");
5737     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'H'))
5738         ajStrAssignC(OEnv, "AP");
5739     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'S'))
5740         ajStrAssignC(OEnv, "AQ");
5741     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'C'))
5742         ajStrAssignC(OEnv, "AR");
5743     else if ((ajStrMatchC(BEnv, "B7")) && (SEnv == 'H'))
5744         ajStrAssignC(OEnv, "AS");
5745     else if ((ajStrMatchC(BEnv, "B7")) && (SEnv == 'S'))
5746         ajStrAssignC(OEnv, "AT");
5747     else if ((ajStrMatchC(BEnv, "B7")) && (SEnv == 'C'))
5748         ajStrAssignC(OEnv, "AU");
5749     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'H'))
5750         ajStrAssignC(OEnv, "AV");
5751     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'S'))
5752         ajStrAssignC(OEnv, "AW");
5753     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'C'))
5754         ajStrAssignC(OEnv, "AX");
5755     else
5756     {
5757         ajStrSetClear(OEnv);
5758         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
5759         ajStrDel(&BEnv);
5760 
5761         return 0;
5762     }
5763 
5764     ajStrDel(&BEnv);
5765 
5766     return 24;
5767 }
5768 
5769 
5770 
5771 
5772 /* @func ajResidueEnv16 *******************************************************
5773 **
5774 ** Assigns environment based on side chain accessibility and secondary
5775 ** structure.  Assigns environment of "*" as default.
5776 **
5777 ** @param [r] residue [const AjPResidue] AJAX Residue
5778 ** @param [r] SEnv [char] Secondary structure environment code
5779 ** @param [w] OEnv [AjPStr*] Character for the overall environment class
5780 ** @param  [w] flog [AjPFile] Log file
5781 ** @return [ajint] Number of environments
5782 **
5783 ** @release 3.0.0
5784 ** @@
5785 ******************************************************************************/
5786 
ajResidueEnv16(const AjPResidue residue,char SEnv,AjPStr * OEnv,AjPFile flog)5787 ajint ajResidueEnv16(const AjPResidue residue, char SEnv, AjPStr *OEnv,
5788                      AjPFile flog)
5789 {
5790     float BLimit = 5.0F;        /* Upper limit for the relative solvent
5791                                  * accessible area for a buried residue */
5792 
5793     float PolLimit1 = 5.0F;
5794     float PolLimit2 = 15.0F;
5795     float PolLimit3 = 25.0F;
5796     float PolLimit4 = 35.0F;
5797     float PolLimit5 = 45.0F;
5798     float PolLimit6 = 75.0F;
5799 
5800     AjPStr BEnv = NULL;
5801 
5802     if (!residue)
5803     {
5804         ajWarn("No residue to ajResidueEnv");
5805 
5806         return 0;
5807     }
5808 
5809     ajStrSetClear(OEnv);
5810     BEnv = ajStrNew();
5811 
5812     ajFmtPrintF(flog, "R:%c-%d S:%c A:%.2f f:%.2f\n",
5813                 residue->Id1, residue->Idx,
5814                 residue->eType, residue->side_rel, residue->pol_rel);
5815 
5816     if ((residue->side_rel <= BLimit) &&
5817         (residue->pol_rel <= PolLimit1))
5818         ajStrAssignC(&BEnv, "B1");
5819     else if ((residue->side_rel <= BLimit) &&
5820              (residue->pol_rel > PolLimit1) &&
5821              (residue->pol_rel <= PolLimit2))
5822         ajStrAssignC(&BEnv, "B2");
5823     else if ((residue->side_rel <= BLimit) &&
5824              (residue->pol_rel > PolLimit2) &&
5825              (residue->pol_rel <= PolLimit3))
5826         ajStrAssignC(&BEnv, "B3");
5827     else if ((residue->side_rel <= BLimit) &&
5828              (residue->pol_rel > PolLimit3) &&
5829              (residue->pol_rel <= PolLimit4))
5830         ajStrAssignC(&BEnv, "B4");
5831     else if ((residue->side_rel <= BLimit) &&
5832              (residue->pol_rel > PolLimit4) &&
5833              (residue->pol_rel <= PolLimit5))
5834         ajStrAssignC(&BEnv, "B5");
5835     else if ((residue->side_rel <= BLimit) &&
5836              (residue->pol_rel > PolLimit5) &&
5837              (residue->pol_rel <= PolLimit6))
5838         ajStrAssignC(&BEnv, "B6");
5839     else if ((residue->side_rel <= BLimit) &&
5840              (residue->pol_rel > PolLimit6))
5841         ajStrAssignC(&BEnv, "B7");
5842     else if ((residue->side_rel > BLimit))
5843         ajStrAssignC(&BEnv, "E");
5844     else
5845     {
5846         ajStrSetClear(OEnv);
5847         ajFmtPrintF(flog, "BEnv unassigned for residue %d\n", residue->Idx);
5848         ajStrDel(&BEnv);
5849 
5850         return 0;
5851     }
5852 
5853     /* Assign overall environment class */
5854     if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'H'))
5855         ajStrAssignC(OEnv, "AA");
5856     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'S'))
5857         ajStrAssignC(OEnv, "AB");
5858     else if ((ajStrMatchC(BEnv, "B1")) && (SEnv == 'C'))
5859         ajStrAssignC(OEnv, "AC");
5860     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'H'))
5861         ajStrAssignC(OEnv, "AD");
5862     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'S'))
5863         ajStrAssignC(OEnv, "AE");
5864     else if ((ajStrMatchC(BEnv, "B2")) && (SEnv == 'C'))
5865         ajStrAssignC(OEnv, "AF");
5866     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'H'))
5867         ajStrAssignC(OEnv, "AG");
5868     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'S'))
5869         ajStrAssignC(OEnv, "AH");
5870     else if ((ajStrMatchC(BEnv, "B3")) && (SEnv == 'C'))
5871         ajStrAssignC(OEnv, "AI");
5872     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'H'))
5873         ajStrAssignC(OEnv, "AJ");
5874     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'S'))
5875         ajStrAssignC(OEnv, "AK");
5876     else if ((ajStrMatchC(BEnv, "B4")) && (SEnv == 'C'))
5877         ajStrAssignC(OEnv, "AL");
5878     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'H'))
5879         ajStrAssignC(OEnv, "AM");
5880     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'S'))
5881         ajStrAssignC(OEnv, "AN");
5882     else if ((ajStrMatchC(BEnv, "B5")) && (SEnv == 'C'))
5883         ajStrAssignC(OEnv, "AO");
5884     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'H'))
5885         ajStrAssignC(OEnv, "AP");
5886     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'S'))
5887         ajStrAssignC(OEnv, "AQ");
5888     else if ((ajStrMatchC(BEnv, "B6")) && (SEnv == 'C'))
5889         ajStrAssignC(OEnv, "AR");
5890     else if ((ajStrMatchC(BEnv, "B7")) && (SEnv == 'H'))
5891         ajStrAssignC(OEnv, "AS");
5892     else if ((ajStrMatchC(BEnv, "B7")) && (SEnv == 'S'))
5893         ajStrAssignC(OEnv, "AT");
5894     else if ((ajStrMatchC(BEnv, "B7")) && (SEnv == 'C'))
5895         ajStrAssignC(OEnv, "AU");
5896     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'H'))
5897         ajStrAssignC(OEnv, "AV");
5898     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'S'))
5899         ajStrAssignC(OEnv, "AW");
5900     else if ((ajStrMatchC(BEnv, "E")) && (SEnv == 'C'))
5901         ajStrAssignC(OEnv, "AX");
5902     else
5903     {
5904         ajStrSetClear(OEnv);
5905         ajFmtPrintF(flog, "OEnv unassigned for residue %d\n", residue->Idx);
5906         ajStrDel(&BEnv);
5907 
5908         return 0;
5909     }
5910 
5911     ajStrDel(&BEnv);
5912 
5913     return 24;
5914 }
5915 
5916 
5917 
5918 
5919 /* @func ajPdbGetEStrideType **************************************************
5920 **
5921 ** Reads a Pdb object and writes a string with the secondary structure. The
5922 ** string that is written is the same length as the full-length chain
5923 ** (regardless of whether coordinates for a residue were available or not)
5924 ** therefore it can be indexed into using residue numbers.  The string is
5925 ** allocated if necessary.  If secondary structure assignment was not available
5926 ** for a residue a '.' is given in the string.
5927 **
5928 ** @param [r] pdb [const AjPPdb] AJAX PDB object
5929 ** @param [r] chn [ajuint]   Chain number
5930 ** @param [w] EStrideType [AjPStr *] String to hold secondary structure
5931 **
5932 ** @return [ajint] Length (residues) of array that was written or -1 (for
5933 **                 an error)
5934 **
5935 ** @release 2.9.0
5936 ** @@
5937 ******************************************************************************/
5938 
ajPdbGetEStrideType(const AjPPdb pdb,ajuint chn,AjPStr * EStrideType)5939 ajint ajPdbGetEStrideType(const AjPPdb pdb, ajuint chn, AjPStr *EStrideType)
5940 {
5941     AjPResidue residue = NULL;
5942     AjIList iter = NULL;
5943     ajuint idx = 0U;
5944 
5945     if (!pdb || !EStrideType || (chn < 1))
5946     {
5947         ajWarn("Bad args passed to ajPdbGetEStrideType");
5948 
5949         return -1;
5950     }
5951 
5952     if (chn > pdb->Nchn)
5953     {
5954         ajWarn("chn arg in ajPdbGetEStrideType exceeds no. chains");
5955 
5956         return -1;
5957     }
5958     else
5959         idx = chn - 1U;
5960 
5961     /* +1 is for the NULL */
5962     if (!*EStrideType)
5963         *EStrideType = ajStrNewRes(pdb->Chains[idx]->Nres + 1U);
5964     else
5965     {
5966         ajStrDel(EStrideType);
5967         *EStrideType = ajStrNewRes(pdb->Chains[idx]->Nres + 1U);
5968     }
5969 
5970     /* Set all positions to . */
5971     ajStrAppendCountK(EStrideType, '.', pdb->Chains[idx]->Nres);
5972 
5973     iter = ajListIterNewread(pdb->Chains[idx]->Residues);
5974 
5975     while ((residue = (AjPResidue) ajListIterGet(iter)))
5976         (*EStrideType)->Ptr[residue->Idx - 1] = residue->eStrideType;
5977 
5978     ajListIterDel(&iter);
5979 
5980     return pdb->Chains[idx]->Nres;
5981 }
5982 
5983 
5984 
5985 
5986 /* ======================================================================= */
5987 /* ============================== Casts ===================================*/
5988 /* ======================================================================= */
5989 
5990 
5991 
5992 
5993 /* @section Casts *************************************************************
5994 **
5995 ** These functions examine the contents of an instance and return some
5996 ** derived information. Some of them provide access to the internal
5997 ** components of an instance. They are provided for programming convenience
5998 ** but should be used with caution.
5999 **
6000 ******************************************************************************/
6001 
6002 
6003 
6004 
6005 /* ======================================================================= */
6006 /* =========================== Reporters ==================================*/
6007 /* ======================================================================= */
6008 
6009 
6010 
6011 
6012 /* @section Reporters *********************************************************
6013 **
6014 ** These functions return the contents of an instance but do not make any
6015 ** changes.
6016 **
6017 ******************************************************************************/
6018 
6019 
6020 
6021 
6022 /* @func ajPdbChnidToNum ******************************************************
6023 **
6024 ** Finds the chain number for a given chain identifier in a pdb structure
6025 **
6026 ** @param [r] identifier [char] Chain identifier
6027 ** @param [r] pdb [const AjPPdb] Pdb object
6028 ** @param [w] chn [ajuint*] Chain number
6029 **
6030 ** @return [AjBool] True on success
6031 **
6032 ** @release 2.9.0
6033 ** @@
6034 ******************************************************************************/
6035 
ajPdbChnidToNum(char identifier,const AjPPdb pdb,ajuint * chn)6036 AjBool ajPdbChnidToNum(char identifier, const AjPPdb pdb, ajuint *chn)
6037 {
6038     ajuint i = 0U;
6039 
6040     for (i = 0U; i < pdb->Nchn; i++)
6041     {
6042         if (toupper((int) pdb->Chains[i]->Id) == toupper((int) identifier))
6043         {
6044             *chn = i + 1;
6045 
6046             return ajTrue;
6047         }
6048 
6049         /*
6050         ** Cope with chain id's of ' ' (which might be given as '.' in
6051         ** the Pdb object)
6052         */
6053         if ((identifier == ' ') && (pdb->Chains[i]->Id == '.'))
6054         {
6055             *chn = i + 1;
6056 
6057             return ajTrue;
6058         }
6059     }
6060 
6061     /*
6062     ** A '.' may be given as the id for domains comprising more than one
6063     ** chain
6064     */
6065     if (identifier == '.')
6066     {
6067         *chn = 1;
6068 
6069         return ajTrue;
6070     }
6071 
6072     return ajFalse;
6073 }
6074 
6075 
6076 
6077 
6078 /* @func ajPdbtospArrFindPdbid ************************************************
6079 **
6080 ** Performs a binary search for a PDB code over an array of Pdbtosp
6081 ** structures (which of course must first have been sorted). This is a
6082 ** case-insensitive search.
6083 **
6084 ** @param [r] array [AjPPdbtosp const *] Array of AjOPdbtosp objects
6085 ** @param [r] size [ajint] Size of array
6086 ** @param [r] identifier [const AjPStr] Search term
6087 **
6088 ** @return [ajint] Index of first Pdbtosp object found with an PDB code
6089 ** matching id, or -1 if id is not found.
6090 **
6091 ** @release 2.9.0
6092 ** @@
6093 ******************************************************************************/
6094 
ajPdbtospArrFindPdbid(AjPPdbtosp const * array,ajint size,const AjPStr identifier)6095 ajint ajPdbtospArrFindPdbid(AjPPdbtosp const *array, ajint size,
6096                             const AjPStr identifier)
6097 {
6098     ajint l = 0;
6099     ajint m = 0;
6100     ajint h = size - 1;
6101     ajint c = 0;
6102 
6103     while (l <= h)
6104     {
6105         m = (l + h) >> 1;
6106 
6107         if ((c = ajStrCmpCaseS(identifier, array[m]->Pdb)) < 0)
6108             h = m - 1;
6109         else if (c > 0)
6110             l = m + 1;
6111         else
6112             return m;
6113     }
6114 
6115     return -1;
6116 }
6117 
6118 
6119 
6120 
6121 /* ======================================================================= */
6122 /* ========================== Input & Output ============================= */
6123 /* ======================================================================= */
6124 
6125 
6126 
6127 
6128 /* @section Input & output ****************************************************
6129 **
6130 ** These functions are used for formatted input and output to file.
6131 **
6132 ******************************************************************************/
6133 
6134 
6135 
6136 
6137 /* @func ajPdbWriteAll ********************************************************
6138 **
6139 ** Writes a clean coordinate file for a protein.
6140 **
6141 ** @param [w] outf [AjPFile] Output file stream
6142 ** @param [r] pdb  [const AjPPdb] AJAX PDB object
6143 **
6144 ** @return [AjBool] True on success
6145 ** @category output [AjPPdb] Writes a ccf-format file for a protein.
6146 **
6147 ** @release 1.9.0
6148 ** @@
6149 ******************************************************************************/
6150 
ajPdbWriteAll(AjPFile outf,const AjPPdb pdb)6151 AjBool ajPdbWriteAll(AjPFile outf, const AjPPdb pdb)
6152 {
6153     ajuint i = 0U;
6154     ajuint j = 0U;
6155     AjIList iter = NULL;
6156     AjPAtom atom = NULL;
6157     AjPResidue residue = NULL;
6158     AjPSeqout outseq = NULL;
6159 
6160     /* Write the header information */
6161 
6162     ajFmtPrintF(outf, "%-5s%S\n", "ID", pdb->Pdb);
6163     ajFmtPrintF(outf, "XX\n");
6164 
6165     ajFmtPrintSplit(outf, pdb->Compnd, "DE   ", 75, " \t\r\n");
6166     ajFmtPrintF(outf, "XX\n");
6167 
6168     ajFmtPrintSplit(outf, pdb->Source, "OS   ", 75, " \t\r\n");
6169     ajFmtPrintF(outf, "XX\n");
6170 
6171     ajFmtPrintF(outf, "%-5sMETHOD ", "EX");
6172 
6173     if (pdb->Method == ajEPdbMethodXray)
6174         ajFmtPrintF(outf, "xray; ");
6175     else
6176         ajFmtPrintF(outf, "nmr_or_model; ");
6177     ajFmtPrintF(outf, "RESO %.2f; NMOD %d; NCHN %d; NGRP %d;\n", pdb->Reso,
6178                 pdb->Nmod, pdb->Nchn, pdb->Ngp);
6179 
6180     /* Write chain-specific information */
6181     for (i = 0U; i < pdb->Nchn; i++)
6182     {
6183         ajFmtPrintF(outf, "XX\n");
6184         ajFmtPrintF(outf, "%-5s[%d]\n",
6185                     "CN",
6186                     i + 1);
6187         ajFmtPrintF(outf, "XX\n");
6188 
6189         ajFmtPrintF(outf, "%-5s", "IN");
6190 
6191         if (pdb->Chains[i]->Id == ' ')
6192             ajFmtPrintF(outf, "ID %c; ", '.');
6193         else
6194             ajFmtPrintF(outf, "ID %c; ", pdb->Chains[i]->Id);
6195 
6196 #if AJFALSE
6197         ajFmtPrintF(outf, "NR %d; NL %d; NH %d; NE %d; NS %d; NT %d;\n",
6198                     pdb->Chains[i]->Nres,
6199                     pdb->Chains[i]->Nlig,
6200                     pdb->Chains[i]->numHelices,
6201                     pdb->Chains[i]->numStrands,
6202                     pdb->Chains[i]->numSheets,
6203                     pdb->Chains[i]->numTurns);
6204 #endif
6205         ajFmtPrintF(outf, "NR %d; NL %d; NH %d; NE %d;\n",
6206                     pdb->Chains[i]->Nres,
6207                     pdb->Chains[i]->Nlig,
6208                     pdb->Chains[i]->numHelices,
6209                     pdb->Chains[i]->numStrands);
6210 #if AJFALSE
6211         ajFmtPrintF(outf, "%-5sID %c; NR %d; NH %d; NW %d;\n",
6212                     "IN",
6213                     pdb->Chains[i]->Id,
6214                     pdb->Chains[i]->Nres,
6215                     pdb->Chains[i]->Nhet,
6216                     pdb->Chains[i]->Nwat);
6217 #endif
6218         ajFmtPrintF(outf, "XX\n");
6219         outseq = ajSeqoutNewFile(outf);
6220         ajSeqoutDumpSwisslike(outseq, pdb->Chains[i]->Seq, "SQ");
6221         ajSeqoutDel(&outseq);
6222     }
6223     ajFmtPrintF(outf, "XX\n");
6224 
6225 /*  printf("NCHN: %d   NMOD: %d\n", pdb->Nchn, pdb->Nmod); */
6226 
6227     /* Write RESIDUES list */
6228     for (i = 1U; i <= pdb->Nmod; i++)
6229     {
6230         for (j = 0U; j < pdb->Nchn; j++)
6231         {
6232             iter = ajListIterNewread(pdb->Chains[j]->Residues);
6233 
6234             while (!ajListIterDone(iter))
6235             {
6236                 residue = (AjPResidue) ajListIterGet(iter);
6237 
6238                 if (residue->Mod > i)
6239                     break;
6240                 else if (residue->Mod != i)
6241                     continue;
6242                 else
6243                 {
6244                     ajFmtPrintF(outf, "%-5s%-5d%-5d%-5d%-6S%-2c%-6S",
6245                                 "RE",
6246                                 residue->Mod,
6247                                 residue->Chn,
6248                                 residue->Idx,
6249                                 residue->Pdb,
6250                                 residue->Id1,
6251                                 residue->Id3);
6252 
6253                     if (residue->eNum != 0)
6254                         ajFmtPrintF(outf, "%-5d", residue->eNum);
6255                     else
6256                         ajFmtPrintF(outf, "%-5c", '.');
6257 
6258                     ajFmtPrintF(outf, "%-5S%-5c", residue->eId, residue->eType);
6259 
6260                     if (residue->eType == 'H')
6261                         ajFmtPrintF(outf, "%-5d", residue->eClass);
6262                     else
6263                         ajFmtPrintF(outf, "%-5c", '.');
6264 
6265                     if (residue->eStrideNum != 0)
6266                         ajFmtPrintF(outf, "%-5d", residue->eStrideNum);
6267                     else
6268                         ajFmtPrintF(outf, "%-5c", '.');
6269 
6270                     ajFmtPrintF(outf, "%-5c", residue->eStrideType);
6271 
6272                     ajFmtPrintF(outf, "%8.2f%8.2f%8.2f%8.2f%8.2f"
6273                                 "%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f"
6274                                 "%8.2f\n",
6275                                 residue->Phi,
6276                                 residue->Psi,
6277                                 residue->Area,
6278                                 residue->all_abs,
6279                                 residue->all_rel,
6280                                 residue->side_abs,
6281                                 residue->side_rel,
6282                                 residue->main_abs,
6283                                 residue->main_rel,
6284                                 residue->npol_abs,
6285                                 residue->npol_rel,
6286                                 residue->pol_abs,
6287                                 residue->pol_rel);
6288                 }
6289             }
6290 
6291             ajListIterDel(&iter);
6292         }
6293     }
6294 
6295     /* Write ATOMS list */
6296     for (i = 1U; i <= pdb->Nmod; i++)
6297     {
6298         for (j = 0U; j < pdb->Nchn; j++)
6299         {
6300             /* Print out chain-specific coordinates */
6301             iter = ajListIterNewread(pdb->Chains[j]->Atoms);
6302 
6303             while (!ajListIterDone(iter))
6304             {
6305                 atom = (AjPAtom) ajListIterGet(iter);
6306 
6307                 if (atom->Mod > i)
6308                     break;
6309                 else if (atom->Mod != i)
6310                     continue;
6311                 else
6312                 {
6313                     if (atom->Type == 'H')
6314                         ajFmtPrintF(outf, "%-5s%-5d%-5d%-5d%-5c%-6S%-2c%-6S"
6315                                     "%-2c%-6S"
6316                                     "%9.3f%9.3f%9.3f%8.2f%8.2f\n",
6317                                     "AT",
6318                                     atom->Mod,
6319                                     atom->Chn,
6320                                     atom->Gpn,
6321                                     '.',
6322                                     atom->Pdb,
6323                                     atom->Id1,
6324                                     atom->Id3,
6325                                     atom->Type,
6326                                     atom->Atm,
6327                                     atom->X,
6328                                     atom->Y,
6329                                     atom->Z,
6330                                     atom->O,
6331                                     atom->B);
6332                     else
6333                     {
6334                         ajFmtPrintF(outf, "%-5s%-5d%-5d%-5c%-5d%-6S%-2c%-6S"
6335                                     "%-2c%-6S"
6336                                     "%9.3f%9.3f%9.3f%8.2f%8.2f\n",
6337                                     "AT",
6338                                     atom->Mod,
6339                                     atom->Chn,
6340                                     '.',
6341                                     atom->Idx,
6342                                     atom->Pdb,
6343                                     atom->Id1,
6344                                     atom->Id3,
6345                                     atom->Type,
6346                                     atom->Atm,
6347                                     atom->X,
6348                                     atom->Y,
6349                                     atom->Z,
6350                                     atom->O,
6351                                     atom->B);
6352                     }
6353                 }
6354             }
6355 
6356             ajListIterDel(&iter);
6357         }
6358 
6359         /* Print out group-specific coordinates for this model */
6360         iter = ajListIterNewread(pdb->Groups);
6361 
6362         while (!ajListIterDone(iter))
6363         {
6364             atom = (AjPAtom) ajListIterGet(iter);
6365 
6366             if (atom->Mod > i)
6367                 break;
6368             else if (atom->Mod != i)
6369                 continue;
6370             else
6371             {
6372                 ajFmtPrintF(outf, "%-5s%-5d%-5c%-5d%-5c%-6S%-2c%-6S%-2c%-6S"
6373                             "%9.3f%9.3f%9.3f%8.2f%8.2f\n",
6374                             "AT",
6375                             atom->Mod,
6376                             '.',
6377                             atom->Gpn,
6378                             '.',
6379                             atom->Pdb,
6380                             atom->Id1,
6381                             atom->Id3,
6382                             atom->Type,
6383                             atom->Atm,
6384                             atom->X,
6385                             atom->Y,
6386                             atom->Z,
6387                             atom->O,
6388                             atom->B);
6389             }
6390         }
6391 
6392         ajListIterDel(&iter);
6393 
6394         /* Print out water-specific coordinates for this model */
6395         iter = ajListIterNewread(pdb->Water);
6396 
6397         while (!ajListIterDone(iter))
6398         {
6399             atom = (AjPAtom) ajListIterGet(iter);
6400 
6401             if (atom->Mod > i)
6402                 break;
6403             else if (atom->Mod != i)
6404                 continue;
6405             else
6406             {
6407                 ajFmtPrintF(outf, "%-5s%-5d%-5c%-5c%-5c%-6S%-2c%-6S%-2c%-6S"
6408                             "%9.3f%9.3f%9.3f%8.2f%8.2f\n",
6409                             "AT",
6410                             atom->Mod,
6411                             '.',
6412                             '.',
6413                             '.',
6414                             atom->Pdb,
6415                             atom->Id1,
6416                             atom->Id3,
6417                             atom->Type,
6418                             atom->Atm,
6419                             atom->X,
6420                             atom->Y,
6421                             atom->Z,
6422                             atom->O,
6423                             atom->B);
6424             }
6425         }
6426 
6427         ajListIterDel(&iter);
6428     }
6429 
6430     ajFmtPrintF(outf, "//\n");
6431 
6432     return ajTrue;
6433 }
6434 
6435 
6436 
6437 
6438 /* @func ajPdbWriteSegment ****************************************************
6439 **
6440 ** Writes a clean coordinate file for a segment, e.g. a domain. The segment
6441 ** corresponds to a sequence that is passed to the function.
6442 ** In the clean coordinate file, the coordinates are presented as belonging
6443 ** to a single chain.  Coordinates for heterogens are NOT written to file.
6444 **
6445 ** @param [w] outf    [AjPFile] Output file stream
6446 ** @param [r] pdb     [const AjPPdb]  Pdb object
6447 ** @param [r] segment [const AjPStr]  Sequence of segment to print out.
6448 ** @param [r] chnid   [char]    Chain id of segment
6449 ** @param [r] domain  [const AjPStr]  Domain code for segment
6450 ** @param [w] errf    [AjPFile] Output file stream for error messages
6451 **
6452 ** @return [AjBool] True on success
6453 **
6454 ** @release 3.0.0
6455 ** @@
6456 **
6457 ******************************************************************************/
6458 
ajPdbWriteSegment(AjPFile outf,const AjPPdb pdb,const AjPStr segment,char chnid,const AjPStr domain,AjPFile errf)6459 AjBool ajPdbWriteSegment(AjPFile outf, const AjPPdb pdb, const AjPStr segment,
6460                          char chnid, const AjPStr domain, AjPFile errf)
6461 {
6462     ajuint chn = 0U;
6463     ajlong start = 0L;
6464     ajlong end = 0L;
6465     char id;
6466 
6467     AjIList iter = NULL;
6468     AjPAtom atm = NULL;
6469     AjPResidue residue = NULL;
6470     AjBool found_start = ajFalse;
6471     AjBool found_end = ajFalse;
6472 
6473     AjPSeqout outseq = NULL;
6474 
6475     /* Check for unknown or zero-length chain */
6476     if (!ajPdbChnidToNum(chnid, pdb, &chn))
6477     {
6478         ajWarn("Chain incompatibility error in "
6479                "ajPbdWriteSegment");
6480 
6481         ajFmtPrintF(errf, "//\n%S\nERROR Chain incompatibility "
6482                     "error in ajPbdWriteDomain\n", domain);
6483 
6484         return ajFalse;
6485     }
6486     else if (pdb->Chains[chn - 1]->Nres == 0)
6487     {
6488         ajWarn("Chain length zero");
6489 
6490         ajFmtPrintF(errf, "//\n%S\nERROR Chain length zero\n",
6491                     domain);
6492 
6493         return ajFalse;
6494     }
6495 
6496     /* Check if segment exists in this chain */
6497     if ((start = ajStrFindS(pdb->Chains[chn - 1]->Seq, segment)) == -1)
6498     {
6499         ajWarn("Domain not found in ajPbdWriteSegment");
6500         ajFmtPrintF(errf, "//\n%S\nERROR Domain not found "
6501                     "in ajPbdWriteSegment\n", domain);
6502 
6503         return ajFalse;
6504     }
6505     else
6506     {
6507         /* Residue numbers start at 1 ! */
6508         start++;
6509         end = start + MAJSTRGETLEN(segment) - 1;
6510     }
6511 
6512     /* Write header info. to domain coordinate file */
6513     ajFmtPrintF(outf, "%-5s%S\n", "ID", domain);
6514     ajFmtPrintF(outf, "XX\n");
6515     ajFmtPrintF(outf, "%-5sCo-ordinates for domain %S\n",
6516                 "DE", domain);
6517     ajFmtPrintF(outf, "XX\n");
6518     ajFmtPrintF(outf, "%-5sDomain defined from sequence segment\n",
6519                 "OS");
6520     ajFmtPrintF(outf, "XX\n");
6521     ajFmtPrintF(outf, "%-5sMETHOD ", "EX");
6522 
6523     if (pdb->Method == ajEPdbMethodXray)
6524         ajFmtPrintF(outf, "xray; ");
6525     else
6526         ajFmtPrintF(outf, "nmr_or_model; ");
6527     /* The NCHN and NMOD are hard-coded to 1 for domain files */
6528     ajFmtPrintF(outf, "RESO %.2f; NMOD 1; NCHN 1; NGRP 0;\n",
6529                 pdb->Reso);
6530 
6531     id = pdb->Chains[chn - 1]->Id;
6532 
6533     if (id == ' ')
6534         id = '.';
6535 
6536     /* Write sequence to domain coordinate file */
6537     ajFmtPrintF(outf, "XX\n");
6538     ajFmtPrintF(outf, "%-5s[1]\n", "CN");
6539     ajFmtPrintF(outf, "XX\n");
6540 
6541     ajFmtPrintF(outf, "%-5sID %c; NR %d; NL 0; NH 0; NE 0;\n",
6542                 "IN",
6543                 id,
6544                 MAJSTRGETLEN(segment));
6545     ajFmtPrintF(outf, "XX\n");
6546     outseq = ajSeqoutNewFile(outf);
6547     ajSeqoutDumpSwisslike(outseq, segment, "SQ");
6548     ajSeqoutDel(&outseq);
6549     ajFmtPrintF(outf, "XX\n");
6550 
6551     /* Write coordinates list to domain coordinate file */
6552     ajPdbChnidToNum(chnid, pdb, &chn);
6553 
6554     /* Initialise the iterator */
6555     iter = ajListIterNewread(pdb->Chains[chn - 1]->Atoms);
6556 
6557     /* Iterate through the list of residues */
6558     while ((residue = (AjPResidue) ajListIterGet(iter)))
6559     {
6560         if (residue->Mod != 1)
6561             break;
6562 
6563         if (!found_start)
6564         {
6565             if (residue->Idx == start)
6566                 found_start = ajTrue;
6567             else
6568                 continue;
6569         }
6570 
6571         if (!found_end)
6572         {
6573             if (residue->Idx == end)
6574                 found_end = ajTrue;
6575         }
6576         /*
6577         ** The end position has been found, and the current residue is
6578         ** not the final residue.
6579         */
6580         else if (residue->Idx != end && found_end)
6581             break;
6582 
6583 
6584         /* Print out coordinate line */
6585         ajFmtPrintF(outf, "%-5s%-5d%-5d%-5d%-6S%-2c%-6S",
6586                     "RE",
6587                     residue->Mod,
6588                     1,          /* chn number is always given as 1 */
6589                     residue->Idx - start + 1,
6590                     residue->Pdb,
6591                     residue->Id1,
6592                     residue->Id3);
6593 
6594         if (residue->eNum != 0)
6595             ajFmtPrintF(outf, "%-5d", residue->eNum);
6596         else
6597             ajFmtPrintF(outf, "%-5c", '.');
6598 
6599         ajFmtPrintF(outf, "%-5S%-5c", residue->eId, residue->eType);
6600 
6601         if (residue->eType == 'H')
6602             ajFmtPrintF(outf, "%-5d", residue->eClass);
6603         else
6604             ajFmtPrintF(outf, "%-5c", '.');
6605 
6606         if (residue->eStrideNum != 0)
6607             ajFmtPrintF(outf, "%-5d", residue->eStrideNum);
6608         else
6609             ajFmtPrintF(outf, "%-5c", '.');
6610 
6611         ajFmtPrintF(outf, "%-5c", residue->eStrideType);
6612 
6613         ajFmtPrintF(outf, "%8.2f%8.2f%8.2f%8.2f%8.2f"
6614                     "%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f"
6615                     "%8.2f\n",
6616                     residue->Phi,
6617                     residue->Psi,
6618                     residue->Area,
6619                     residue->all_abs,
6620                     residue->all_rel,
6621                     residue->side_abs,
6622                     residue->side_rel,
6623                     residue->main_abs,
6624                     residue->main_rel,
6625                     residue->npol_abs,
6626                     residue->npol_rel,
6627                     residue->pol_abs,
6628                     residue->pol_rel);
6629 
6630         /* Assign pointer for this chain */
6631         /* residue2 = residue;   but it's never used */
6632     }
6633 
6634     ajListIterDel(&iter);
6635 
6636     /* Iterate through the list of atoms */
6637     while ((atm = (AjPAtom) ajListIterGet(iter)))
6638     {
6639         if (atm->Mod != 1)
6640             break;
6641 
6642         if (atm->Type != 'P')
6643             continue;
6644 
6645         if (!found_start)
6646         {
6647             if (atm->Idx == start)
6648                 found_start = ajTrue;
6649             else
6650                 continue;
6651         }
6652 
6653         if (!found_end)
6654         {
6655             if (atm->Idx == end)
6656                 found_end = ajTrue;
6657         }
6658         /*
6659         ** The end position has been found, and the current atom no longer
6660         ** belongs to this final residue.
6661         */
6662         else if (atm->Idx != end && found_end)
6663             break;
6664 
6665         /* Print out coordinate line */
6666         ajFmtPrintF(outf, "%-5s%-5d%-5d%-5c%-5d%-6S%-2c%-6S%-2c%-6S"
6667                     "%9.3f%9.3f%9.3f%8.2f%8.2f\n"
6668                     "AT",
6669                     atm->Mod,   /* It will always be 1 */
6670                     1,          /* chn number is always given as 1 */
6671                     '.',
6672                     atm->Idx - start + 1,
6673                     atm->Pdb,
6674                     atm->Id1,
6675                     atm->Id3,
6676                     atm->Type,
6677                     atm->Atm,
6678                     atm->X,
6679                     atm->Y,
6680                     atm->Z,
6681                     atm->O,
6682                     atm->B);
6683 
6684         /* Assign pointer for this chain */
6685         /* atm2 = atm; but it's never used */
6686     }
6687 
6688     ajListIterDel(&iter);
6689 
6690     /* Write last line in file */
6691     ajFmtPrintF(outf, "//\n");
6692 
6693     return ajTrue;
6694 }
6695 
6696 
6697 
6698 
6699 /* @func ajHetWrite ***********************************************************
6700 **
6701 ** Writes the contents of a Het object to file.
6702 **
6703 ** @param [w] outf    [AjPFile]   Output file
6704 ** @param [r] het     [const AjPHet] AJAX Het
6705 ** @param [r] dogrep  [AjBool]    Flag (True if we are to write 'cnt'
6706 **                                element of the Het object to file).
6707 **
6708 ** @return [AjBool] True on success
6709 ** @category output [AjPHet] Write Het object to file in clean
6710 **
6711 ** @release 2.9.0
6712 ** @@
6713 ******************************************************************************/
6714 
ajHetWrite(AjPFile outf,const AjPHet het,AjBool dogrep)6715 AjBool ajHetWrite(AjPFile outf, const AjPHet het, AjBool dogrep)
6716 {
6717     ajuint i = 0U;
6718 
6719     /* Check arg's */
6720     if (!outf || !het)
6721         return ajFalse;
6722 
6723     for (i = 0U; i < het->Number; i++)
6724     {
6725         ajFmtPrintF(outf, "ID   %S\n", het->Entries[i]->abv);
6726         ajFmtPrintSplit(outf, het->Entries[i]->ful, "DE   ", 70, " \t\n\r");
6727         ajFmtPrintSplit(outf, het->Entries[i]->syn, "SY   ", 70, " \t\n\r");
6728 
6729         if (dogrep)
6730             ajFmtPrintF(outf, "NN   %d\n", het->Entries[i]->cnt);
6731 
6732         ajFmtPrintF(outf, "//\n");
6733     }
6734 
6735     return ajTrue;
6736 }
6737 
6738 
6739 
6740 
6741 /* @func ajPdbtospWrite *******************************************************
6742 **
6743 ** Reads a list of Pdbtosp objects, e.g. taken from the swissprot:pdb
6744 ** equivalence table available at URL:
6745 **  (1) http://www.expasy.ch/cgi-bin/lists?pdbtosp.txt)
6746 ** and writes the list out to file in embl-like format (see
6747 ** documentation for DOMAINATRIX "pdbtosp" application).
6748 **
6749 ** @param [w] outf  [AjPFile] Output file
6750 ** @param [r] list  [const AjPList] List of Pdbtosp objects
6751 **
6752 ** @return [AjBool] True of file was written ok.
6753 **
6754 ** @release 2.9.0
6755 ** @@
6756 ******************************************************************************/
6757 
ajPdbtospWrite(AjPFile outf,const AjPList list)6758 AjBool ajPdbtospWrite(AjPFile outf, const AjPList list)
6759 {
6760     ajuint i = 0;
6761 
6762     AjIList iter = NULL;
6763     AjPPdbtosp pdbtosp = NULL;
6764 
6765     if (!outf || !list)
6766     {
6767         ajWarn("Bad args passed to ajPdbtospWrte");
6768 
6769         return ajFalse;
6770     }
6771 
6772     iter = ajListIterNewread(list);
6773 
6774     while ((pdbtosp = (AjPPdbtosp) ajListIterGet(iter)))
6775     {
6776         ajFmtPrintF(outf, "%-5s%S\nXX\n%-5s%u\nXX\n",
6777                     "EN", pdbtosp->Pdb, "NE", pdbtosp->Number);
6778 
6779         for (i = 0U; i < pdbtosp->Number; i++)
6780             ajFmtPrintF(outf, "%-5s%S ID; %S ACC;\n",
6781                         "IN", pdbtosp->Spr[i], pdbtosp->Acc[i]);
6782 
6783         ajFmtPrintF(outf, "XX\n//\n");
6784     }
6785 
6786     ajListIterDel(&iter);
6787 
6788     return ajTrue;
6789 }
6790 
6791 
6792 
6793 
6794 /* @func ajCmapWrite **********************************************************
6795 **
6796 ** Write a Cmap object to file in CON format (see documentation for
6797 ** DOMAINATRIX "contacts" application).
6798 **
6799 ** @param [u] outf    [AjPFile]  Output file stream.
6800 ** @param [r] cmap    [const AjPCmap]  Cmap object pointer.
6801 **
6802 ** @return [AjBool] True on success (object was written successfully)
6803 ** @category output [AjPCmap] Write Cmap object to file in CON format.
6804 **
6805 ** @release 3.0.0
6806 ** @@
6807 ******************************************************************************/
6808 
ajCmapWrite(AjPFile outf,const AjPCmap cmap)6809 AjBool ajCmapWrite(AjPFile outf, const AjPCmap cmap)
6810 {
6811     ajint x = 0;
6812     ajint y = 0;
6813     AjPStr Id = NULL;
6814     AjPStr Domid = NULL;
6815     AjPStr Ligid = NULL;
6816     AjPStr res1 = NULL;
6817     AjPStr res2 = NULL;
6818     AjPSeqout outseq = NULL;
6819 
6820     if (!cmap || !outf)
6821         return ajFalse;
6822 
6823     Id = ajStrNew();
6824     Domid = ajStrNew();
6825     Ligid = ajStrNew();
6826     res1 = ajStrNew();
6827     res2 = ajStrNew();
6828 
6829     /* EN */
6830     ajFmtPrintF(outf, "%-5s[%d]\n", "EN", cmap->en);
6831     ajFmtPrintF(outf, "XX\n");
6832 
6833     /* ID */
6834     if (MAJSTRGETLEN(cmap->Id))
6835         ajStrAssignS(&Id, cmap->Id);
6836     else
6837         ajStrAssignC(&Id, ".");
6838 
6839     if (MAJSTRGETLEN(cmap->Domid))
6840         ajStrAssignS(&Domid, cmap->Domid);
6841     else
6842         ajStrAssignC(&Domid, ".");
6843 
6844     if (MAJSTRGETLEN(cmap->Ligid))
6845         ajStrAssignS(&Ligid, cmap->Ligid);
6846     else
6847         ajStrAssignC(&Ligid, ".");
6848 
6849     ajFmtPrintF(outf, "%-5sPDB %S; DOM %S; LIG %S;\n",
6850                 "ID",
6851                 Id, Domid, Ligid);
6852     ajFmtPrintF(outf, "XX\n");
6853 
6854     /* DE */
6855     ajFmtPrintF(outf, "DE   %S\n", cmap->Desc);
6856     ajFmtPrintF(outf, "XX\n");
6857 
6858     /* SI */
6859     ajFmtPrintF(outf, "%-5sSN %d; NS %d\n", "SI", cmap->sn, cmap->ns);
6860     ajFmtPrintF(outf, "XX\n");
6861 
6862     /* CN */
6863     if ((cmap->Type == ajECmapTypeIntra) || (cmap->Type == ajECmapTypeLigand))
6864         ajFmtPrintF(outf, "%-5sMO .; CN1 %d; CN2 .; ID1 %c; ID2 .; "
6865                     "NRES1 %d; NRES2 .\n",
6866                     "CN",
6867                     cmap->Chn1,
6868                     cmap->Chid1,
6869                     cmap->Nres1);
6870     else if (cmap->Type == ajECmapTypeInter)
6871         ajFmtPrintF(outf, "%-5sMO .; CN1 %d; CN2 %d; ID1 %c; ID2 %c; "
6872                     "NRES1 %d; NRES2 %d\n",
6873                     "CN",
6874                     cmap->Chn1,
6875                     cmap->Chn2,
6876                     cmap->Chid1,
6877                     cmap->Chid2,
6878                     cmap->Nres1,
6879                     cmap->Nres2);
6880     else
6881         ajFatal("cmap type not known in ajCmapWrite");
6882 
6883 
6884     /* S1 */
6885     if (MAJSTRGETLEN(cmap->Seq1))
6886     {
6887         outseq = ajSeqoutNewFile(outf);
6888         ajSeqoutDumpSwisslike(outseq, cmap->Seq1, "S1");
6889         ajSeqoutDel(&outseq);
6890         ajFmtPrintF(outf, "XX\n");
6891     }
6892 
6893     /* S2 */
6894     if (cmap->Type == ajECmapTypeInter)
6895     {
6896         if (MAJSTRGETLEN(cmap->Seq2))
6897         {
6898             outseq = ajSeqoutNewFile(outf);
6899             ajSeqoutDumpSwisslike(outseq, cmap->Seq2, "S2");
6900             ajSeqoutDel(&outseq);
6901             ajFmtPrintF(outf, "XX\n");
6902         }
6903     }
6904 
6905     /* NC */
6906     if ((cmap->Type == ajECmapTypeIntra) || (cmap->Type == ajECmapTypeInter))
6907     {
6908         ajFmtPrintF(outf, "%-5sSM %d; LI .\n", "NC", cmap->Ncon);
6909         ajFmtPrintF(outf, "XX\n");
6910     }
6911     else
6912     {
6913         ajFmtPrintF(outf, "%-5sSM .; LI %d\n", "NC", cmap->Ncon);
6914         ajFmtPrintF(outf, "XX\n");
6915     }
6916 
6917     /* SM or LI */
6918     if (cmap->Type == ajECmapTypeIntra)
6919     {
6920         for (x = 0; x < cmap->Nres1; x++)
6921             for (y = x + 1; y < cmap->Nres1; y++)
6922             {
6923                 if ((ajUint2dGet(cmap->Mat, x, y) == 1))
6924                 {
6925                     /* Assign residue id. */
6926                     if (!ajResidueToTriplet(ajStrGetCharPos(cmap->Seq1, x),
6927                                             &res1))
6928                         ajFatal("Index out of range in ajCmapWrite");
6929 
6930                     if (!ajResidueToTriplet(ajStrGetCharPos(cmap->Seq1, y),
6931                                             &res2))
6932                         ajFatal("Index out of range in ajCmapWrite");
6933 
6934                     /* Print out the contact. */
6935                     ajFmtPrintF(outf, "%-5s%S %d ; %S %d\n", "SM", res1, x + 1,
6936                                 res2, y + 1);
6937                 }
6938             }
6939     }
6940     else if (cmap->Type == ajECmapTypeInter)
6941     {
6942         for (x = 0; x < cmap->Nres1; x++)
6943             for (y = x + 1; y < cmap->Nres2; y++)
6944             {
6945                 if ((ajUint2dGet(cmap->Mat, x, y) == 1))
6946                 {
6947                     /* Assign residue id. */
6948                     if (!ajResidueToTriplet(ajStrGetCharPos(cmap->Seq1, x),
6949                                             &res1))
6950                         ajFatal("Index out of range in ajCmapWrite");
6951 
6952                     if (!ajResidueToTriplet(ajStrGetCharPos(cmap->Seq2, y),
6953                                             &res2))
6954                         ajFatal("Index out of range in ajCmapWrite");
6955 
6956                     /* Print out the contact. */
6957                     ajFmtPrintF(outf, "%-5s%S %d ; %S %d\n", "SM", res1, x + 1,
6958                                 res2, y + 1);
6959                 }
6960             }
6961     }
6962     else if (cmap->Type == ajECmapTypeLigand)
6963     {
6964         for (x = 0; x < cmap->Nres1; x++)
6965             if ((ajUint2dGet(cmap->Mat, 0, x) == 1))
6966             {
6967                 /* Assign residue id. */
6968                 if (!ajResidueToTriplet(ajStrGetCharPos(cmap->Seq1, x), &res1))
6969                     ajFatal("Index out of range in ajCmapWrite");
6970 
6971                 /* Print out the contact. */
6972                 ajFmtPrintF(outf, "%-5s%S %d\n", "LI", res1, x + 1);
6973             }
6974     }
6975 
6976     ajFmtPrintF(outf, "//\n");
6977 
6978     ajStrDel(&Id);
6979     ajStrDel(&Domid);
6980     ajStrDel(&Ligid);
6981     ajStrDel(&res1);
6982     ajStrDel(&res2);
6983 
6984     return ajTrue;
6985 }
6986 
6987 
6988 
6989 
6990 /* @func ajPdbExit ************************************************************
6991 **
6992 ** Cleanup of Pdb function internals.
6993 **
6994 ** @return [void]
6995 **
6996 ** @release 6.1.0
6997 ** @@
6998 ******************************************************************************/
6999 
ajPdbExit(void)7000 void ajPdbExit(void)
7001 {
7002     ajStrDel(&pdbGStrline);
7003     ajStrDel(&pdbGStrtemp_id);
7004     ajStrDel(&pdbGStrtemp_domid);
7005     ajStrDel(&pdbGStrtemp_ligid);
7006     ajStrDel(&pdbGStrtype);
7007     ajStrDel(&pdbGStrdesc);
7008     ajStrDel(&pdbGStrtmpstr);
7009 
7010     return;
7011 }
7012 
7013 
7014 
7015 
7016 /* ======================================================================= */
7017 /* ======================== Miscellaneous =================================*/
7018 /* ======================================================================= */
7019 
7020 
7021 
7022 
7023 /* @section Miscellaneous *****************************************************
7024 **
7025 ** These functions may have diverse functions that do not fit into the other
7026 ** categories.
7027 **
7028 ******************************************************************************/
7029