File: docking_project.c

package info (click to toggle)
garlic 1.6-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 4,516 kB
  • sloc: ansic: 52,465; makefile: 2,254
file content (233 lines) | stat: -rw-r--r-- 7,016 bytes parent folder | download | duplicates (5)
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
/* Copyright (C) 2000 Damir Zucic */

/*=============================================================================

			docking_project.c

Purpose:
	Prepare orthogonal projection of  the specified complex.  There
	are two complexes: bottom (1) and top (2).  The purpose of this
	function is to find the exposed  candidates for hydrogen bonds.
	Atomic positions are taken  relative to the plane center of the
	first complex and projected to xz plane.

Input:
	(1) Pointer to RuntimeS structure.
	(2) The index of  the complex   which should  be projected.  Do
	    not confuse  this index with  the actual  macromol. complex
	    index!  The values allowed here are 1 (bottom) and 2 (top).

Output:
	(1) The array of indices, which are listing exposed atoms, will
	    be prepared.
	(2) Return value.

Return value:
	(1) Positive on success.
	(2) Negative on failure.

Notes:
	(1) The index of exposed atom is of the type int, though size_t
	    is used elsewhere. The reason is that int may have negative
	    value,  while size_t is unsigned on many systems.  Negative
	    values are used to signal that data  stored to a given cell
	    are obsolete.

	(2) Indentation is exceptionally 4 spaces.

========includes:============================================================*/

#include <stdio.h>

#include <math.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>

#include "defines.h"
#include "typedefs.h"

/*======function prototypes:=================================================*/

void		ErrorMessage_ (char *, char *, char *,
			       char *, char *, char *, char *);

/*======prepare orthogonal projection of the specified complex:==============*/

int DockingProject_ (RuntimeS *runtimeSP, int docking_complexI)
{
MolComplexS		*curr_mol_complexSP;
int			*exposed_atomIP;
ExposedResidueS		*exposed_polarSP;
double			x0, z0;
size_t			atomsN, atomI;
double			reciprocal_denominator;
int			matrix_width, elementsN, matrixI;
int			exposed_polarI;
int			atom_half_width;
AtomS			*curr_atomSP;
double			x, y, z;
double			relative_x, relative_z;
double			d;
int			central_rowI, central_columnI;
int			row0I, row1I, column0I, column1I;
int			rowI, columnI, combinedI;
int			*curr_cellP;
int			prev_atomI;
double			old_y;

/* Check the complex index and prepare the pointers: */
if (docking_complexI == 1)
    {
    curr_mol_complexSP = runtimeSP->mol_complex1SP;
    exposed_atomIP = runtimeSP->exposed_atom1IP;
    exposed_polarSP = runtimeSP->exposed_polar1SP;
    }
else if (docking_complexI == 2)
    {
    curr_mol_complexSP = runtimeSP->mol_complex2SP;
    exposed_atomIP = runtimeSP->exposed_atom2IP;
    exposed_polarSP = runtimeSP->exposed_polar2SP;
    }
else
    {
    ErrorMessage_ ("garlic", "DockingProject_", "",
		   "Bad macromolecular complex index!\n",
		   "", "", "");
    return -1;
    }

/* The reference (central) point is the center of the */
/* plane associated with  the first (bottom) complex. */
/* Here it is shifted for half of docking area width: */
x0 = runtimeSP->mol_complex1SP->planeS.center_x[0] -
     runtimeSP->docking_area_width / 2;
z0 = runtimeSP->mol_complex1SP->planeS.center_z[0] -
     runtimeSP->docking_area_width / 2;

/* Prepare and check the number of atoms: */
atomsN = curr_mol_complexSP->atomsN;
if (atomsN == 0) return -2;

/* Initialize the matrix of indices; negative value in some cell */
/* is used  to signal  that no atom was projected  to this cell: */
matrix_width = runtimeSP->docking_matrix_width;
elementsN = matrix_width * matrix_width;
for (matrixI = 0; matrixI < elementsN; matrixI++)
    {
    *(exposed_atomIP + matrixI) = -1;
    }

/* Reset excludedF flags: */
for (exposed_polarI = 0;
     exposed_polarI < MAX_EXPOSED_RESIDUES;
     exposed_polarI++)
	{
	(exposed_polarSP + exposed_polarI)->excludedF = 0;
	}

/* Atom radius in cells: */
if (runtimeSP->docking_cell_width != 0.0)
    {
    d = DOCKING_ATOM_RADIUS / runtimeSP->docking_cell_width;
    atom_half_width = (int) d;
    }
else atom_half_width = 0;

/* Auxilliary variable: */
if (runtimeSP->docking_cell_width != 0.0)
    {
    reciprocal_denominator = 1.0 / runtimeSP->docking_cell_width;
    }
else reciprocal_denominator = 0.0;

/* Scan the macromolecular complex: */
for (atomI = 0; atomI < atomsN; atomI++)
    {
    /* Pointer to the current atom: */
    curr_atomSP = curr_mol_complexSP->atomSP + atomI;

    /* x and z coordinate of the current atom: */
    x = curr_atomSP->raw_atomS.x[0];
    z = curr_atomSP->raw_atomS.z[0];

    /* y coordinate of the current atom: */
    y = curr_atomSP->raw_atomS.y;

    /* Coordinates  relative to  the upper left corner */
    /* of the area which is covered by docking matrix: */
    relative_x = x - x0;
    relative_z = z - z0;

    /* Matrix indices of the central point: row index depends on */
    /* relative_x and column index  depends on relative_z value: */
    d = floor (relative_x * reciprocal_denominator); 
    central_rowI = (int) d;
    d = floor (relative_z * reciprocal_denominator);
    central_columnI = (int) d;

    /* Scan the neighbourhood: */
    row0I = central_rowI - atom_half_width;
    row1I = central_rowI + atom_half_width;
    column0I = central_columnI - atom_half_width;
    column1I = central_columnI + atom_half_width;
    for (rowI = row0I; rowI <= row1I; rowI++)
	{
	/* The allowed range is from 0 to matrix_width: */
	if ((rowI < 0) || (rowI >= matrix_width)) continue;

	for (columnI = column0I; columnI <= column1I; columnI++)
	    {
	    /* The allowed range is from 0 to matrix_width: */
	    if ((columnI < 0) || (columnI >= matrix_width)) continue;

	    /* Prepare the combined array index (the matrix is */
	    /* stored in  the form of  one-dimensional array): */
	    combinedI = rowI * matrix_width + columnI;

	    /* Prepare the pointer to the current cell: */
	    curr_cellP = exposed_atomIP + combinedI;

	    /* The index of the atom reffered by the stored atomic index: */
	    prev_atomI = *curr_cellP;

	    /* If some atomic index was stored to the cell defined by */
	    /* rowI and columnI,  compare  y coordinates  of the atom */
	    /* reffered by this index and  the current atom.  For the */
	    /* bottom complex,  the obscured atom has higher y, while */
	    /* for  the top complex  the obscured atom  has lower  y. */
	    if (prev_atomI >= 0)
		{
		/* The y coordinate of the atom reffered by stored index: */
		old_y = (curr_mol_complexSP->atomSP + prev_atomI)->raw_atomS.y;

		/* If projecting bottom complex: */
		if (docking_complexI == 1)
		    {
		    if (old_y < y) continue;
		    }

		/* If projecting top complex: */
		else
		    {
		    if (old_y > y) continue;
		    }
		}

	    /* If this point is reached, the current atom is not obscured. */

	    /* Store the index of the current atom to the matrix: */
	    *curr_cellP = atomI;
	    }
	}
    }

/* Return positive value on success: */
return 1;
}

/*===========================================================================*/