-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathprobe.c
6695 lines (6044 loc) · 272 KB
/
probe.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*{{{--probe.c general comments */
/* name: probe.c */
/* author: J. Michael Word */
/* date written: 2/26/96 */
/* purpose: compute intersecton surfaces */
/*****************************************************************/
/* NOTICE: This is free software and the source code is freely */
/* available. You are free to redistribute or modify under the */
/* conditions that (1) this notice is not removed or modified */
/* in any way and (2) any modified versions of the program are */
/* also available for free. */
/* ** Absolutely no Warranty ** */
/* Copyright (C) 1996-2013 J. Michael Word */
/*****************************************************************/
/*Updated to work with the remediated PDB names rmi 070727 */
/* Essentially ennumerated additional possible atom names and added */
/* the residue name info to the routine that assigns element type */
/*Jan 2006 DCR compromise comments to enable jEdit type folding {{{ }}} */
/* without messing up vi type beginning-end bracket identification shift % */
/* So jEdit folds have to stay within code regions, esp subroutines 060129*/
/*Oct 2004 DCR modifications to version 2.10.031014 starting with dcr041007 */
/*dcr: sorry Mike, but changing to Berkeley-Altman brackets really helps me!*/
/*i.e. some routines changed: opening and closing brackets vertically in line*/
/*also substituted spaces for tabs which are not robust across text editors*/
/*also tend to shorten lines to <=80 col, standard card-image window size*/
/*which many text editors use as a default width*/
/*050111: in trying to track behavior of autobondrot mode, the lack of */
/*global mode state is a severe limitation. */
/*probe trys to be so object oriented as to not have global modal states */
/*but given the existance of a whole slew of probe.c global parameters, */
/*a few more would only help clear up dependencies and program flow! */
/*hence logical Lautobondrot as a probe.c global*/
/* modifications: see dump_changes() */
/*}}}--probe.c general comments */
/*{{{--includes and declarations (globals for probe.c) */
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "probe.h"
#define INLINE_FOR_SPEED 1
static char* versionString = "probe: version 2.26.021123, Copyright 1996-2016, J. Michael Word; 2021-2023 Richardson Lab";
static char* shortVersionStr = "probe.2.26.021123";
static char *referenceString = "Word, et. al. (1999) J. Mol. Biol. 285, 1711-1733.";
static char *electronicReference = "http://kinemage.biochem.duke.edu/";
static int LweakHbonds = FALSE; /*111215dcr global Logical to group weak H-bonds*/
static int LworseOverlap = FALSE; /* 04/09/2015 SJ - to separate the bad and worse overlaps if set to true*/
static int LOneDotEach = FALSE; /*111013 global One Dot for Each neighbor */
static int Lnearest = FALSE; /*111021dcr selection only on nearest neighbor*/
static int Lfilternearest = FALSE;/*111022dcr final filter nearest by extraPat*/
static int Lfilterocc1 = FALSE; /*20120120dcr final filter use only OCC==1 */
static int Lfilternoalt = FALSE; /*20120120dcr final filter exclude any alts */
static int Lgapbins = FALSE; /*111020dcr gapbin ptmasters*/
static int LXHvector = FALSE; /*20120120dcr for H: vector parent--H--Target angle*/
static int Ldotdump = FALSE; /* global flag for Ldotdump messages in examineDots*/
static int Lhonlyocclude = FALSE; /*130427dcr global flag: only Hatoms can occlude*/
static pattern *extraPat = NULL;/*111022dcr finally filter nearest by extraPat*/
static pattern *causePat = NULL;/*111022dcr initial select nearest by targPat*/
static pattern *sourcePat= NULL;/*111021dcr select src bases on srcPat */
static int LMasterName = FALSE; /*global extra master={name} on lists 060129*/
static int LMergeContacts = TRUE; /*global combine wide & close contacts 060129*/
/*static int Lautobondrot = FALSE;*/ /* global flag for AUTOBONDROT mode 050111*/
static int ImplicitH = FALSE; /* global controling dot radii */
static int UsePolarH = TRUE; /* global controling VDW radii of polar Hs */
static int Verbose = TRUE; /* global flag for output messages */
static int DoMcMc = FALSE; /* global controling mainchain->mainchain dots */
static int DoHet = TRUE; /* global controling non-Water HET dots */
static int DoH2O = TRUE; /* global controling Water dots */
static int DoWatWat = FALSE; /* global controling water->water dots */
static int LimitDots = TRUE; /* global controling chopping around bumps*/
static int LensDots = FALSE; /* global controling lens keyword in kin file*/
static int ColorGap = TRUE; /* global controling coloration of Gaps */
static int ByNABaseColor= FALSE; /* global controling coloration of dots */
static int DumpNewHO = FALSE; /*global controling dump of water newH atom data*/
static int Maxbonded = 4; /* global controling exclusion bond count */
static int UseStdBond= FALSE; /* global flag: if TRUE std AA and NA bonding assumed */
static int UseHParent= TRUE; /* global flag: bonding based on parent names on std H atoms */
static int ShowTicks = TRUE; /* global controling display of residue name ticker */
static int OldStyleU = FALSE; /* global controling -u output (true gives kiss edge stuff) */
static int SplitBySegID=FALSE;/* global controling the splitting of residues (-SEGID) */
static int HB2aromFace=TRUE; /* global controling aromatic face Hbonding */
static int AtomMasters=FALSE; /* global controling use of masters */
static int PermitCHXHB=FALSE; /* global controling use CHX (CHO) hbonds */
static int DebugLevel= 0; /* global controling debugging information */
int NuclearRadii = FALSE; /* global controling Hydrogen vdW radii, cannot be static */
#ifdef JACKnANDREA
static int writeHbonds = FALSE; /* global flag: if true, write out Hbonds every time they are detected */
#endif
static int OutputFmtType = 0; /* global selecting output format */
/* 0 ==> kinemage format */
/* 1 ==> O format */
/* 2 ==> XtalView format */
/* 3 ==> oneline multi:count:dcr041101*/
static int OutputHBs = TRUE; /* global controling display of contact categories */
static int OutputClashes = TRUE; /* global controling display of contact categories */
static int OutputVDWs = TRUE; /* global controling display of contact categories */
static int OnlyBadOut = FALSE; /* global controling display of contact categories dcr041010*/
static int ContactSUMMARY = FALSE; /* global controling output of contact summaries dcr041101*/
static float Min_regular_hb_cutoff=0.6f; /* globals controling hbond cutoff */
static float Min_charged_hb_cutoff=0.8f; /* defaults set in processCommandline() */
static float RadScaleFactor =1.0; /* global VDW radius scale Factor r*f */
static float RadScaleOffset =0.0; /* global VDW radius scale Offset r+o */
static float CORadScale =(float)(1.65/ATOMC_EXPLICIT_VDW); /* global VDW radius scale Factor for C=O */
static float GAPweight =0.25;/* global raw GAP score weight */
static float BUMPweight =10.0;/* global raw BUMP score scale Factor */
static float HBweight = 4.0;/* global raw HBond score scale Factor */
static float CHOHBfactor = 0.5;/* global CH..O HBond score scale Factor */
static float LowGoodCut =-0.4f;/* global cutoff for good bin */
static float HighGoodCut = 0.25;/* global cutoff for good bin */
static float WorseBumpCut =-0.5; /* SJ 04/10/2015 - global cutoff for worse overlap*/
static float OccupancyCutoff =0.02f; /* global occupancy below which atom has presence but no clashes */
/*unfortunately, one needs intervening atoms to avoid clashes between atoms*/
/*that are separated by <= Maxbonded, which thus needs to pass through any*/
/*atom no matter what it's own occupancy happens to be */
/*050118 atom->occ < OccupancyCutoff neither clash nor transfer bonded info*/
/* so flanking atoms show horrible spurious clashes (e.g. 1BKR lys 5 lys 78*/
/*mechanism seems to be atom->flags | IGNORE_FLAG */
/*050119 atoms irrespective of occ now put into neighbor bins for bonding*/
/* but atom->occ < OccupancyCutoff are not allowed to show clashes*/
static int OccupancyCriteria = TRUE; /*global: use occupancy criteria 060831*/
/*explicit default: unset by -noocc flag, 060831*/
static char *OutPointColor = "gray";
static pointSet COdots; /* adjustible radius dots for C=O carbon */
/*Old: dcr041020 NODEWIDTH defined 5 probe.h, hard code 6 to match initialization*/
/*Old: 0 wide contact,1 close contact,2 small overlap,3 bad overlap,4 H-bonds*/
/*Old: 5 running sum which can be tested for existance of any of these spikes*/
/* New 04/15/2015 SJ: 0 wide contact,1 close contact,2 weak H bonds, 3 small overlap, 4 bad overlap, 5 worse overlap, 6 H-bonds*/
/* changing the size of the array to 8*/
static long mcmccont[2][8] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /*dcr041017,dcr041020, SJ 04/15/2015*/
static long scsccont[2][8] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /*dcr041017,dcr041020, SJ 04/15/2015*/
static long mcsccont[2][8] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /*dcr041017,dcr041020, SJ 04/15/2015*/
static long othrcont[2][8] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /*dcr041017,dcr041020, SJ 04/15/2015*/
static long summcont[2][8] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /*dcr041017,dcr041020, SJ 04/15/2015*/
/* comment: the above number 8 should not be hardcoded, maybe initialize in the main function? - SJ 04/09/2015*/
static char inputfilename[256]; /*dcr041023 global, subroutines can report it*/
static int modelNumber[100]; /*global record of incoming model # 041114*/
static int modelCount = 0; /*global count of such records, all files 041114*/
static int modelLimit = 0; /*global loop's flag for multiple models 041114*/
/*model counting simple-minded only good for one input file cases like SELF*/
static int modelSrc = 0; /*global model specified for source 041114*/
static int modelTarg = 0; /*global model specified for target 041114*/
static int modelToProcess = 0; /*global model specified for processing 041114*/
static char* dumpFileName = 0; /* global name of file to dump atom info to (default none) */
#define ATOMS_IN_THE_SAME_RES(aa, bb) IS_THE_SAME_RES((aa)->r, (bb)->r)
/*041112 IS_THE_SAME_RES() cannot avoid modeltest, i.e. implied Lmodeltest==1*/
#define IS_THE_SAME_RES(ra, rb) \
( ((ra) == (rb)) \
||( (ra)->resid == (rb)->resid \
&& (ra)->resInsCode == (rb)->resInsCode \
&& strcmp((ra)->chain, (rb)->chain) == 0 \
&& (ra)->model == (rb)->model ) \
&& ((SplitBySegID == FALSE) || ( strcmp((ra)->segid, (rb)->segid) == 0) ) )
#define TRACEATOM(where, txt, atptr, endtxt) \
(fprintf((where), "%s{%s%c %s%d%c}[%d]%s", (txt),\
(atptr)->atomname, (atptr)->altConf,\
(atptr)->r->resname, (atptr)->r->resid,\
(atptr)->r->resInsCode, (atptr)->r->rescnt, (endtxt)))
/*}}}--includes and declarations */
/*{{{main()***************************** MAIN ********************************/
int main(int argc, char **argv) {
int rc = 0;
FILE *outf = stdout;
initalizeAtomTbl(); /*atomprops.c*/
initStdConnTable(); /*stdconntable.c*/
inputfilename[0] = '\0'; /*global dcr041023*/
rc = mainProbeProc(argc, argv, outf);
return rc;
}
/*}}}main()__________________________________________________________________*/
/*{{{mainProbeProc()******** called from main() ******************************/
int mainProbeProc(int argc, char **argv, FILE *outf)
{/*mainProbeProc()*/
int method;
int keepUnselected;
region boundingBoxA;
atom *a, *allMainAtoms = NULL;
atomBins *abins = NULL;
pointSet dots[NUMATOMTYPES];
char *srcArg=NULL, *targArg=NULL, *extraArg=NULL, *ignoreArg=NULL; /* extraArg dcr 111022*/
char *groupLabel=NULL;
pattern *srcPat = NULL, *targPat = NULL, *ignorePat = NULL;
float density, probeRad, spikelen;
int drawSpike, countDots, rawOutput, sayGroup, addKinToFile, conFlag; //conFlag by SJ - 10/07/2011
char message[200];
movingAtomBuildInfo mabis;
residue *resLst = NULL;
FILE* dumpFile = NULL;
/*mabis moving atom build info structure */
/*buffer to pass data to newMovingAtom for autobondrot*/
allMainAtoms = processCommandline(argc, argv, &method,
&boundingBoxA, &density, &probeRad,
&drawSpike, &spikelen, &countDots, &keepUnselected,
&srcArg, &targArg, &extraArg, &ignoreArg, &groupLabel, &rawOutput, &conFlag,
&sayGroup, &addKinToFile, &mabis, &resLst);//conFlag by SJ -10/07/2011
/*called with address of mabis, i.e. mabip moving atom build info ptr */
/*autobondrot mode: not read in any mobile atoms yet*/
/*though may have static set of atoms already in. */
/* dumpRes(resLst); */
if ((allMainAtoms == NULL) && (mabis.inf == NULL))
{
/*static atoms read into allMainAtoms linked list, */
/* and/or autobondrot file name for mobile atoms held in mabis.inf */
sprintf(message, "No atom data in input.");
note(message);
}
else
{/*there are atoms for probe to work on...*/
if (Verbose)
{/*Verbose: lots of stuff to screen...*/
note(versionString);
sprintf(message, "density: %g, probe radius: %g, maxBonded: %d",
density, probeRad, Maxbonded);
note(message);
sprintf(message, "regular HB cutoff: %g, charged HB cutoff: %g",
Min_regular_hb_cutoff, Min_charged_hb_cutoff);
note(message);
sprintf(message,
"Dot gap bins: low to %g, %g to 0, 0 to %g, %g to high, & Hbonds",
LowGoodCut, LowGoodCut, HighGoodCut, HighGoodCut);
note(message);
if (RadScaleOffset < -0.0001 || RadScaleOffset > 0.0001) {
sprintf(message, "Add %g to VDW Rradius",
RadScaleOffset);
note(message);
}
if (RadScaleFactor < 0.9999 || RadScaleFactor > 1.0001) {
sprintf(message, "Scale VDW Rradius by %g",
RadScaleFactor);
note(message);
}
sprintf(message, "C=O carbon VDW scaled by %.3f to a radius of %g A",
CORadScale, CORadScale* ATOMC_EXPLICIT_VDW);
note(message);
if (rawOutput || countDots) {
sprintf(message, "Score Weights: gapWt=%g, bumpWt=%g, HBWt=%g",
GAPweight, BUMPweight, HBweight);
note(message);
}
if (drawSpike) {
sprintf(message, "draw spike, len: %g", spikelen);
note(message);
}
if (ImplicitH) {
note("implicit hydrogens");
}
if (PermitCHXHB) {
sprintf(message, "CH..O type hbonds recognized (scale factor %g)", CHOHBfactor);
note(message);
}
if (!DoMcMc) {
note("Excluding mainchain-mainchain interactions");
}
if (!DoHet && !DoH2O) {
note("Excluding both HET groups and waters");
}
else {
if (!DoHet) {
note("Excluding non-water HET groups");
}
if (!DoH2O) {
note("Excluding waters");
}
else if (!DoWatWat) {
note("Excluding water-water interactions");
}
}
if (LimitDots) {
note("Limiting dots from bumps to max non-bump cap");
}
if (rawOutput) { /* nothing required for raw format */
}
else if (OutputFmtType == 1) {
note("Formatting for display in O");
}
else if (OutputFmtType == 2) {
note("Formatting for display in XtalView");
}
else if (OutputFmtType == 3) { /*dcr041101*/
note("outputing one line colon:deliminated:counts:by:severity:type:");
}
if (ByNABaseColor) {
if (ColorGap) {
note("Coloring dots by gap (& list color by nucleic acid base)");
}
else {
note("Coloring dots by nucleic acid base");
}
}
else if (ColorGap) {
note("Coloring dots by gap (& list color by atom)");
}
if (!UsePolarH) {
note("Using old (long) radii for polar H atoms");
}
if (!OutputHBs) {
note("Attention: ***Output not generated for H-Bond contacts***");
}
if (!OutputClashes) {
note("Attention: ***Output not generated for clashes***");
}
if (!OutputVDWs) {
note("Attention: ***Output not generated for van der Waals contacts***");
}
if (OnlyBadOut) {
note("Attention: ***Output only generated for Bad Clashes***");/*dcr041010*/
}
if (!keepUnselected) {
note("Attention: ***Unselected atoms dropped (ignored)***");
}
}/*Verbose: lots of stuff to screen...*/
/*now do some work...*/
if( addKinToFile && (OutputFmtType == 0)
&& (! countDots) && (! rawOutput) ) {
fprintf(outf, "@kinemage 1\n");
}
srcPat = getPat(srcArg, "pattern 1", Verbose);
sourcePat = getPat(srcArg, "pattern 1", Verbose);/*111021dcr*/
modelSrc = modelInPattern(srcPat); /*parse.c 041114*/
if(Verbose && modelSrc > 0)
{
sprintf(message, "specified src model==%d", modelSrc);
note(message);
}
targPat = getPat(targArg, "pattern 2", Verbose);
causePat = getPat(targArg, "pattern 2", Verbose); /*111021dcr nearest*/
modelTarg = modelInPattern(targPat); /*parse.c 041114*/
if(Verbose && modelSrc > 0)
{
sprintf(message, "specified targ model==%d", modelTarg);
note(message);
}
extraPat = getPat(extraArg,"extra", Verbose); /*111023dcr*/
ignorePat = getPat(ignoreArg,"ignore", Verbose);
loadDotSpheres(dots, density);
if (allMainAtoms) /*atoms usually read in from processCommandline()*/
{ /*build the bins for all static atoms*/
selectSource(allMainAtoms, srcPat, SET1, targPat, SET2, ignorePat);
abins = binAtoms(allMainAtoms, &boundingBoxA,
'a', probeRad, keepUnselected, SET1|SET2);
}
else /*but autobondrot mode may not yet have read in any atoms*/
{/*minimal boundingBoxes setup*/
boundingBoxA.min.x = boundingBoxA.min.y = boundingBoxA.min.z = 0.0;
boundingBoxA.max.x = boundingBoxA.max.y = boundingBoxA.max.z = 0.1;
abins = initBins('a', &boundingBoxA, 1); /* dummy bbox */
}
if (mabis.inf == NULL) /*pseudo modal flag for autobondrot*/
{/*there is NOT an autobondrot atom info input file */
if (! ImplicitH)
{ /*preliminary step acts on all atoms*/
updateHydrogenInfo(outf, allMainAtoms, abins,
NULL, NULL, SET1|SET2, FALSE);
/*(returned param used on separate call for autobondrot processing)*/
/*e.g. creates: newH->elem = atomHOd , dummy Hydrogen to make an H-Bond*/
}
/* Dump the atom information if we've been asked to. */
if (dumpFileName) {
dumpFile = fopen(dumpFileName, "wb");
for (a = allMainAtoms; a; a = a->next) {
/* Don't dump Phantom Hydrogen information. */
if (a->elem != atomHOd) {
fprintf(dumpFile, "%s %s %3d %-4s %c %7.3f %7.3f %7.3f %5.2f %s %s %s\n",
a->r->chain, a->r->resname, a->r->resid, a->atomname,
a->altConf == ' ' ? '-' : a->altConf,
a->loc.x, a->loc.y, a->loc.z, a->radius,
a->props & ACCEPTOR_PROP ? "isAcceptor" : "noAcceptor",
a->props & DONOR_PROP ? "isDonor" : "noDonor",
a->props & METAL_PROP ? "isMetallic" : "noMetallic");
}
}
fclose(dumpFile);
}
/*now do the real work: */
doCommand(outf, method,
allMainAtoms, abins, NULL, NULL,
dots, probeRad, density, spikelen,
countDots, rawOutput, conFlag, "", 0.0, drawSpike,
sayGroup, groupLabel, argc, argv, message);
}
else
{/*setup to call autobondrot*/
xformDatabase* xdb = NULL;
movingCommandInfo mcis;
mcis.firstPass = TRUE;
mcis.keepUnselected = keepUnselected;
mcis.outf = outf;
mcis.method = method;
mcis.allMainAtoms = allMainAtoms;
mcis.waterClones= NULL;
mcis.abins = abins;
mcis.dots = dots;
mcis.probeRad = probeRad;
mcis.density = density;
mcis.spikelen = spikelen;
mcis.countDots = countDots;
mcis.rawOutput = rawOutput;
mcis.drawSpike = drawSpike;
mcis.sayGroup = sayGroup;
mcis.groupLabel = groupLabel;
mcis.argc = argc;
mcis.argv = argv;
mcis.message = message;
mabis.srcPat = srcPat;
mabis.targPat = targPat;
#define RAW_HEADER_COMMENT "#"
descrCommand(outf, RAW_HEADER_COMMENT, RAW_HEADER_COMMENT, argc, argv);
/*now actually read in both the mobile atoms and transformation info*/
xdb = readTransformationDatabase(mabis.inf, outf, newMovingAtom, &mabis,
movingAtomListProcessing, NULL,
RAW_HEADER_COMMENT);
/* mabis.inf == FILE *inf */
/* outf == FILE *outf */
/* newMovingAtom == abrMkAtomProc mkAtom */
/* &mabis == void *atomstuff */
/* movingAtomListProcessing == abrAtomListProc inputListProc */
/* NULL == void *liststuff */
/* RAW_HEADER_COMMENT == char *cch */
/*autobondrot/readTransformationDatabase() */
/* also calls autobondrot/describeXformDB() */
/* which writes the header-comments to the .map file! */
if (mabis.close) { fclose(mabis.inf); }
autobondrot(stderr, xdb, movingDoCommand, &mcis,
deleteMovingAtom, &mabis, Verbose);
/*autobondrot.c/autobondrot() is the call to do the autobondrot stuff*/
/*movingDoCommand is the name of the probeProc() called from there */
/*probe.c/movingDoCommand() in turn calls probe.c/doCommand()*/
discardXformDB(xdb, deleteMovingAtom, &mabis);
}/*setup to call autobondrot*/
/*after finish, then drop through to here to release memory, etc.*/
disposeBins(abins); abins = NULL;
freeDotSphere(&COdots);
unloadDotSpheres(dots);
freePattern(ignorePat); ignorePat = NULL;
freePattern(targPat); targPat = NULL;
freePattern(srcPat); srcPat = NULL;
freePattern(sourcePat); sourcePat = NULL; /*111023dcr*/
freePattern(causePat); causePat = NULL; /*111023dcr*/
freePattern(extraPat); extraPat = NULL; /*111023dcr*/
if (Verbose)
{
note("If you publish work which uses probe, please cite:");
note(referenceString);
sprintf(message, "For more information see %s", electronicReference);
note(message);
}
}/*there are atoms for probe to work on...*/
disposeListOfResidues(resLst); resLst = NULL;
disposeListOfAtoms(allMainAtoms); allMainAtoms = NULL;
return 0; /*to probe.c/main() */
}/*mainProbeProc()*/
/*}}}mainProbeProc()_________________________________________________________*/
/*{{{newMovingAtom()**********************************************************/
atom * newMovingAtom(char *rec, void *userdata)
{
atom* a = NULL;
movingAtomBuildInfo *m = (movingAtomBuildInfo *)userdata;
if (rec == NULL) { return NULL; }
if (m->scratchRes == NULL) {
m->scratchRes = newResidueData();
}
/*atom * newAtom(char *rec, int file, int model, residue * resDataBuf)*/
a = newAtom(rec, m->filenum, 0, m->scratchRes);
if (a) {
a->next = NULL;
if (ImplicitH && isHatom(a->elem)) {
deleteAtom(a); /* filter out implicit hydrogens */
return NULL;
}
selectSource(a, m->srcPat, SET1, m->targPat, SET2, NULL);
/* note: new moving atom can not be ignored using -IGNORE flag */
if (*(m->reslstptr) == NULL) {/* first residue goes on residue list */
*(m->reslstptr) = m->scratchRes;
m->scratchRes = NULL;
}
else { /* otherwise we have to compare residue data blocks */
if (resDiffersFromPrev(*(m->reslstptr), m->scratchRes)) {
m->scratchRes->nextRes = *(m->reslstptr);
*(m->reslstptr) = m->scratchRes;
m->scratchRes = NULL;
}
else {
a->r = *(m->reslstptr); /* same, so point to prior block */
a->r->a = a; /* makes this atom the head of atom list for this res */
}
}
}
return a;
}
/*}}}newMovingAtom()_________________________________________________________*/
/*{{{deleteMovingAtom()*******************************************************/
void deleteMovingAtom(atom *a, void *userdata)
{
movingAtomBuildInfo *m = (movingAtomBuildInfo *)userdata;
if (m && m->scratchRes) {
deleteResidueData(m->scratchRes); /* clean up extra memory */
m->scratchRes = NULL;
}
deleteAtom(a);
}
/*}}}deleteMovingAtom()______________________________________________________*/
/*{{{movingDoCommand()********************************************************/
void movingDoCommand(char* orientationName, double scoreBias,
atom *allMovingAtoms, void *userdata)
{/*movingDoCommand() for autobondrot*/
/*orientationName holds the angle values as a character string*/
/* NOTE: allMainAtoms/abins & allMovingAtoms/bbins must be disjoint */
/* sets of atoms (none in common) or allMovingAtoms/bbins can */
/* be NULL. */
/* allMovingAtoms refers to autobondrot set of atoms */
movingCommandInfo *m = (movingCommandInfo *)userdata;
region boundingBoxB, nonMovingBB;
atom *a = NULL;
atomBins *bbins = NULL;
/*autobondrot.c: alst == atom *allMovingAtoms existance implies autobondrot*/
if (allMovingAtoms) {
boundingBoxB.min = allMovingAtoms->loc;
boundingBoxB.max = allMovingAtoms->loc;
for(a = allMovingAtoms; a; a = a->next) {
updateBoundingBox(&(a->loc), &boundingBoxB);
}
/* Expand bounding box because of extra water hydrogens */
/* added in updateHydrogenInfo() */
nonMovingBB.min = m->abins->min;
nonMovingBB.max = m->abins->max;
addBBox2BBox(&nonMovingBB, &boundingBoxB);
bbins = binAtoms(allMovingAtoms, &boundingBoxB, 'b', m->probeRad,
m->keepUnselected, SET1|SET2);
if (m->abins == NULL || bbins == NULL) {
halt("no atoms for autobondrot processing");
}
if (! ImplicitH) {
if (m->firstPass) {
m->waterClones = updateHydrogenInfo(m->outf, m->allMainAtoms,
m->abins, allMovingAtoms, bbins, SET1|SET2, TRUE);
m->firstPass = FALSE;
}
else {
/*the DONOR prop tells updateHydrogenInfo() to build H? atoms*/
for(a = m->waterClones; a; a = a->next) {
if ((a->props & AMBIGWATER_PROP) && (a->elem == atomO)) {
a->props |= DONOR_PROP; /* turn water donor property back on*/
}
} /* since each pass through updateHydrogenInfo turns it off */
for(a = allMovingAtoms; a; a = a->next) {
if ((a->props & AMBIGWATER_PROP) && (a->elem == atomO)) {
a->props |= DONOR_PROP; /* turn water donor property back on*/
}
} /* since each pass through updateHydrogenInfo turns it off */
updateHydrogenInfo(m->outf, m->waterClones, m->abins,
allMovingAtoms, bbins, SET1|SET2, FALSE);
}
}
/*autobondrot at this stage has m->method == INTERSECTONCE == 1 */
/* or m->method == SELFINTERSECT == 3 (seems as given in probe command)*/
/* and m->countDots==1, m->rawOutput==1, m->drawSpike==1 */
/* orientationName==rawname== char* holding angle values */
doCommand(m->outf, m->method,
m->allMainAtoms, m->abins,
allMovingAtoms, bbins,
m->dots, m->probeRad, m->density, m->spikelen,
m->countDots, m->rawOutput, FALSE, orientationName, scoreBias,
m->drawSpike, m->sayGroup, m->groupLabel,
m->argc, m->argv, m->message); // SJ -10/07/2011 by default no condensed output for this
/*allMovingAtoms is closest thing to a flag for autobondrot mode*/
disposeBins(bbins);
}
}/*movingDoCommand() for autobondrot*/
/*}}}movingDoCommand()_______________________________________________________*/
/*{{{doCommand()******* called from mainProbeProc() ***calls writeOutput()****/
void doCommand(FILE *outf, int method,
atom *allMainAtoms, atomBins *abins,
atom *allMovingAtoms, atomBins *bbins,
pointSet dots[], float probeRad, float density, float spikelen,
int countDots, int rawOutput, int conFlag, char* rawname, double scoreBias,
int drawSpike, int sayGroup, char* groupLabel,
int argc, char **argv, char message[])
{
/* NOTE: allMainAtoms/abins & allMovingAtoms/bbins must be disjoint */
/* sets of atoms (none in common) or allMovingAtoms/bbins can */
/* be NULL. */
/* allMovingAtoms refers to autobondrot set of atoms */
/*doCommand is called from mainProbeProc() with rawname=="" */
/* and called from movingDoCommand() with rawname==orientationName */
/* which holds the string of the current autobondrot cycle's angle values*/
/*for autobondrot: method is set by probe command, e.g. */
/* INTERSECTONCE==1 as used in example of mobile sidechain in a protein */
/* SELFINTERSECT==3 as used by alaphitaupsi ramachandran calculation*/
/* autobondrot option defines: countDots==1, rawOutput==1*/
/* autobondrot seems to get here with: drawSpike==1*/
dotNode *rslts[NUMATOMTYPES][NODEWIDTH];
int nsel = 0, numSkinDots = 0;
int usesMovingAtoms = FALSE;
int j=0;
char extrastr[32]; /*060129 for extra master to control orig vs fitted dots*/
/*allMovingAtoms is closest thing to a flag for autobondrot mode*/
/*so if it exists and bbins exist (dcr?: mobile atoms near enough?) */
/*then usesMovingAtoms becomes the flag for autobondrot mode */
/*in effect probe is modal but too object oriented to admit such globalness*/
usesMovingAtoms = ((allMovingAtoms != NULL) && (bbins != NULL));
if (! usesMovingAtoms)
{
allMovingAtoms = NULL;
bbins = NULL;
}
initResults(rslts);
if (!countDots && rawOutput && Verbose)
{ /*write rawOutput col headers*/
if (OldStyleU)
{
if(conFlag)
note(">>name:pat:type:srcAtom:targAtom:dot-count:min-gap:gap:"
"kissEdge2BullsEye:dot2BE:dot2SC:spike:score:"
"stype:ttype:x:y:z:sBval:tBval");
else
note(">>name:pat:type:srcAtom:targAtom:min-gap:gap:"
"kissEdge2BullsEye:dot2BE:dot2SC:spike:score:"
"stype:ttype:x:y:z:sBval:tBval");
}
else
{
if(conFlag)
note(">>name:pat:type:srcAtom:targAtom:dot-count:min-gap:gap:"
"spX:spY:spZ:spikeLen:score:"
"stype:ttype:x:y:z:sBval:tBval");
else
note(">>name:pat:type:srcAtom:targAtom:min-gap:gap:"
"spX:spY:spZ:spikeLen:score:"
"stype:ttype:x:y:z:sBval:tBval");
}
}/*write rawOutput col headers*/
if (method == SELFINTERSECT)
{/*{{{(method == SELFINTERSECT)___expected default method___****/
if (Verbose && !(countDots && rawOutput))
note("SelfIntersect");
/*SELFINTERSECT case, using one input file (and where srcPat == targPat)*/
/*is where unwashed NMR files with multiple models can be processed */
/*when there is not a single model specified in the pattern.*/
/*This uses a loop through all the model numbers actually in the file.*/
if(modelSrc == 0 && modelTarg == 0 && modelCount > 1) /*041114*/ /*multiple models in file but no model specified in pattern*/
modelLimit = modelCount;
else
modelLimit = 1;
for(j = 1; j <= modelLimit; j++) /*041114*/
{/*loop over models*/
if(modelLimit > 1)
{/*defines the multiple model case*/
modelToProcess = modelNumber[j]; /*models can be in any order 041114*/
if(Verbose)
fprintf(stderr,"processing modelNumber== %d\n",modelNumber[j]);
}
if(j > 1)
{
freeResults(rslts);
initResults(rslts);
}
genDotIntersect(allMainAtoms, abins, allMovingAtoms, bbins,dots, probeRad, spikelen,SET1, SET1, rslts);
/*does this for all atoms... calls examineDots()*/
if (countDots)
{/*autobondrot sets this, commandline can set this*/
if (!rawOutput) {descrCommand(outf, "program:", "command:", argc, argv);}
numSkinDots = enumDotSkin(allMainAtoms, abins, allMovingAtoms, bbins, dots, SET1);
/*numSkinDots used to normalize output score*/
if (!rawOutput)
{
fprintf(outf, "selection: self\nname: %s\n", groupLabel?groupLabel:"dots");
fprintf(outf, "density: %.1f dots per A^2\nprobeRad: %.3f A\nVDWrad: (r * %.3f) + %.3f A\n",
density, probeRad, RadScaleFactor, RadScaleOffset);
fprintf(outf, "score weights: gapWt=%g, bumpWt=%g, HBWt=%g\n",
GAPweight, BUMPweight, HBweight);
}
if (usesMovingAtoms)
nsel = countSelected(allMainAtoms, SET1) + countSelected(allMovingAtoms, SET1);
else
nsel = countSelected(allMainAtoms, SET1);
if (rawOutput)
{/*autobondrot sets this*/
rawEnumerate(outf, "", rslts, method,
nsel, drawSpike, FALSE, numSkinDots, density,
groupLabel?groupLabel:"", rawname, scoreBias);
}
else
{
enumerate(outf, "self dots", rslts, probeRad, method, nsel,
drawSpike, FALSE, numSkinDots, density);
}
}/*countDots*/
else
{
if (rawOutput)
{
writeRaw(outf, "1->1", rslts, probeRad,groupLabel?groupLabel:"", density,conFlag);
}
else if (OutputFmtType == 1)
writeAltFmtO(outf, TRUE, TRUE, "self_dots", rslts, drawSpike);
else if (OutputFmtType == 2)
{
descrCommand(outf, "# software:", "# command:", argc, argv);
writeAltFmtXV(outf, TRUE, TRUE, "self_dots", rslts, drawSpike);
}
else if (OutputFmtType == 3)
{ /*dcr041101 ONELINE :count:summaries:*/
countsummary(outf,"SelfIntersect", 1, 1); /*dcr041101 Lines,Pass*/
}
else
{/*kinemage output*/
if(ContactSUMMARY) /*dcr041101 Lines,Pass*/
countsummary(outf,"SelfIntersect", 9, 1);
descrCommand(outf, "@caption", " command:", argc, argv);
if (sayGroup)
{
if(modelLimit > 1)
{/*doing jth of multiple models of an ensemble*/
fprintf(outf, "@group dominant {%s M%d} animate\n",groupLabel?groupLabel:"dots",j);
}
else
fprintf(outf, "@group dominant {%s}\n",groupLabel?groupLabel:"dots");
}
sprintf(extrastr,"%s",groupLabel?groupLabel:"dots"); /*060129*/
writeOutput(outf, "self dots", rslts, drawSpike, method, extrastr, probeRad);
/*add probeRad 20111220dcr*/
}/*kinemage output*/
}
}/*loop over models*/
}/*}}}(method == SELFINTERSECT)________________________________*/
else if (method == INTERSECTONCE)
{/*{{{(method == INTERSECTONCE)*********************************/
if (Verbose && !(countDots && rawOutput))
note("IntersectOnce");
genDotIntersect(allMainAtoms, abins, allMovingAtoms, bbins,dots, probeRad, spikelen, SET1, SET2, rslts);
if (countDots)
{/*autobondrot sets this*/
if (!rawOutput)
descrCommand(outf, "program:", "command:", argc, argv);
numSkinDots = enumDotSkin(allMainAtoms, abins, allMovingAtoms, bbins, dots, SET1);
/*numSkinDots used to normalize output score*/
if (!rawOutput)
{
fprintf(outf, "selection: once\nname: %s\n", groupLabel?groupLabel:"dots");
fprintf(outf, "density: %.1f dots per A^2\nprobeRad: %.3f A\nVDWrad: (r * %.3f) + %.3f A\n",
density, probeRad, RadScaleFactor, RadScaleOffset);
fprintf(outf, "score weights: gapWt=%g, bumpWt=%g, HBWt=%g\n",
GAPweight, BUMPweight, HBweight);
}
if (usesMovingAtoms)
nsel = countSelected(allMainAtoms, SET1) + countSelected(allMovingAtoms, SET1);
else
nsel = countSelected(allMainAtoms, SET1);
if (rawOutput)
{/*autobondrot sets this*/
rawEnumerate(outf,"", rslts, method, nsel,
drawSpike, FALSE, numSkinDots, density,
groupLabel?groupLabel:"", rawname, scoreBias);
}
else
{
enumerate(outf,"once dots", rslts, probeRad, method, nsel,
drawSpike, FALSE, numSkinDots, density);
}
}
else
{
if (rawOutput)
{
writeRaw(outf, "1->2", rslts, probeRad,groupLabel?groupLabel:"", density,conFlag);
}
else if (OutputFmtType == 1)
writeAltFmtO(outf, TRUE, TRUE, "once_dots", rslts, drawSpike);
else if (OutputFmtType == 2)
{
descrCommand(outf, "# software:", "# command:", argc, argv);
writeAltFmtXV(outf, TRUE, TRUE, "once_dots", rslts, drawSpike);
}
else if (OutputFmtType == 3)
{ /*dcr041101 ONELINE :count:summaries:*/
countsummary(outf,"IntersectOnce", 1, 1); /*dcr041101 Lines,Pass*/
}
else
{/*write kinemage*/
if(ContactSUMMARY) /*dcr041101 Lines,Pass*/
countsummary(outf,"IntersectOnce", 9, 1);
descrCommand(outf, "@caption", " command:", argc, argv);
if (sayGroup)
fprintf(outf, "@group dominant {%s}\n", groupLabel?groupLabel:"dots");
sprintf(extrastr,"%s",groupLabel?groupLabel:"dots"); /*060129*/
writeOutput(outf, "once dots", rslts, drawSpike, method, extrastr, probeRad);
/*add probeRad 20111220dcr*/
}
}
}/*}}}(method == INTERSECTONCE)________________________________*/
else if (method == INTERSECTBOTHWAYS)
{/*{{{(method == INTERSECTBOTHWAYS)*****************************/
if (Verbose && !(countDots && rawOutput))
note("IntersectBothWays");
if (countDots)
{
if (!rawOutput)
{
descrCommand(outf, "program:", "command:", argc, argv);
fprintf(outf, "selection: both\nname: %s\n", groupLabel?groupLabel:"dots");
fprintf(outf, "density: %.1f dots per A^2\nprobeRad: %.3f A\nVDWrad: (r * %.3f) + %.3f A\n",
density, probeRad, RadScaleFactor, RadScaleOffset);
fprintf(outf, "score weights: gapWt=%g, bumpWt=%g, HBWt=%g\n",
GAPweight, BUMPweight, HBweight);
}
}
else
{
if (rawOutput) {}
/* do nothing on purpose */
else if (OutputFmtType == 1) {}
else if (OutputFmtType == 2)
descrCommand(outf, "# software:", "# command:", argc, argv);
else
{/*kinemage: keywords before double pass*/
descrCommand(outf, "@caption", " command:", argc, argv);
if (sayGroup)
fprintf(outf, "@group {%s}\n",groupLabel?groupLabel:"dots");
}
}
genDotIntersect(allMainAtoms, abins, allMovingAtoms, bbins,
dots, probeRad, spikelen, SET1, SET2, rslts);
if (countDots)
{
numSkinDots = enumDotSkin(allMainAtoms, abins, allMovingAtoms, bbins, dots, SET1);
/*numSkinDots used to normalize output score*/
if (usesMovingAtoms)
nsel = countSelected(allMainAtoms, SET1) + countSelected(allMovingAtoms, SET1);
else
nsel = countSelected(allMainAtoms, SET1);
if (rawOutput)
{
rawEnumerate(outf, "1->2", rslts, method, nsel,
drawSpike, FALSE, numSkinDots, density,
groupLabel?groupLabel:"", rawname, scoreBias);
}
else
{
enumerate(outf, "1->2", rslts, probeRad, method, nsel,
drawSpike, FALSE, numSkinDots, density);
}
}
else
{
if (rawOutput)
{
writeRaw(outf, "1->2", rslts, probeRad, groupLabel?groupLabel:"", density,conFlag);
}
else if (OutputFmtType == 1)
writeAltFmtO(outf, TRUE, !sayGroup, "1->2", rslts, drawSpike);
else if (OutputFmtType == 2)
writeAltFmtXV(outf, TRUE, !sayGroup, "1->2", rslts, drawSpike);
else if (OutputFmtType == 3)
{ /*dcr041101 ONELINE :count:summaries:*/
countsummary(outf,"IntersectBothWays 1->2", 1, 0);
/*dcr041101 Lines,Pass==0 no output for this pass*/
}
else
{
sprintf(extrastr,"%s",groupLabel?groupLabel:"dots"); /*060129*/
writeOutput(outf, "1->2", rslts, drawSpike, method, extrastr,probeRad);
/*add probeRad 20111220dcr*/
if(ContactSUMMARY) /*dcr041101 Lines,Pass*/
countsummary(outf,"IntersectBothWays 1->2", 9, 0);
/*dcr041101 Lines,Pass==0 no output for this pass*/
}
}
freeResults(rslts);
initResults(rslts);
genDotIntersect(allMainAtoms, abins, allMovingAtoms, bbins,
dots, probeRad, spikelen, SET2, SET1, rslts);
if (countDots)
{
numSkinDots = enumDotSkin(allMainAtoms, abins, allMovingAtoms, bbins, dots, SET2);
/*numSkinDots used to normalize output score*/
if (usesMovingAtoms)
nsel = countSelected(allMainAtoms, SET2) + countSelected(allMovingAtoms, SET2);
else
nsel = countSelected(allMainAtoms, SET2);