1
/* Copyright (C) 2000 Damir Zucic */
3
/*=============================================================================
8
Prepare orthogonal projection of the specified complex. There
9
are two complexes: bottom (1) and top (2). The purpose of this
10
function is to find the exposed candidates for hydrogen bonds.
11
Atomic positions are taken relative to the plane center of the
12
first complex and projected to xz plane.
15
(1) Pointer to RuntimeS structure.
16
(2) The index of the complex which should be projected. Do
17
not confuse this index with the actual macromol. complex
18
index! The values allowed here are 1 (bottom) and 2 (top).
21
(1) The array of indices, which are listing exposed atoms, will
26
(1) Positive on success.
27
(2) Negative on failure.
30
(1) The index of exposed atom is of the type int, though size_t
31
is used elsewhere. The reason is that int may have negative
32
value, while size_t is unsigned on many systems. Negative
33
values are used to signal that data stored to a given cell
36
(2) Indentation is exceptionally 4 spaces.
38
========includes:============================================================*/
45
#include <X11/Xutil.h>
47
#include <X11/Xatom.h>
52
/*======function prototypes:=================================================*/
54
void ErrorMessage_ (char *, char *, char *,
55
char *, char *, char *, char *);
57
/*======prepare orthogonal projection of the specified complex:==============*/
59
int DockingProject_ (RuntimeS *runtimeSP, int docking_complexI)
61
MolComplexS *curr_mol_complexSP;
63
ExposedResidueS *exposed_polarSP;
66
double reciprocal_denominator;
67
int matrix_width, elementsN, matrixI;
72
double relative_x, relative_z;
74
int central_rowI, central_columnI;
75
int row0I, row1I, column0I, column1I;
76
int rowI, columnI, combinedI;
81
/* Check the complex index and prepare the pointers: */
82
if (docking_complexI == 1)
84
curr_mol_complexSP = runtimeSP->mol_complex1SP;
85
exposed_atomIP = runtimeSP->exposed_atom1IP;
86
exposed_polarSP = runtimeSP->exposed_polar1SP;
88
else if (docking_complexI == 2)
90
curr_mol_complexSP = runtimeSP->mol_complex2SP;
91
exposed_atomIP = runtimeSP->exposed_atom2IP;
92
exposed_polarSP = runtimeSP->exposed_polar2SP;
96
ErrorMessage_ ("garlic", "DockingProject_", "",
97
"Bad macromolecular complex index!\n",
102
/* The reference (central) point is the center of the */
103
/* plane associated with the first (bottom) complex. */
104
/* Here it is shifted for half of docking area width: */
105
x0 = runtimeSP->mol_complex1SP->planeS.center_x[0] -
106
runtimeSP->docking_area_width / 2;
107
z0 = runtimeSP->mol_complex1SP->planeS.center_z[0] -
108
runtimeSP->docking_area_width / 2;
110
/* Prepare and check the number of atoms: */
111
atomsN = curr_mol_complexSP->atomsN;
112
if (atomsN == 0) return -2;
114
/* Initialize the matrix of indices; negative value in some cell */
115
/* is used to signal that no atom was projected to this cell: */
116
matrix_width = runtimeSP->docking_matrix_width;
117
elementsN = matrix_width * matrix_width;
118
for (matrixI = 0; matrixI < elementsN; matrixI++)
120
*(exposed_atomIP + matrixI) = -1;
123
/* Reset excludedF flags: */
124
for (exposed_polarI = 0;
125
exposed_polarI < MAX_EXPOSED_RESIDUES;
128
(exposed_polarSP + exposed_polarI)->excludedF = 0;
131
/* Atom radius in cells: */
132
if (runtimeSP->docking_cell_width != 0.0)
134
d = DOCKING_ATOM_RADIUS / runtimeSP->docking_cell_width;
135
atom_half_width = (int) d;
136
atom_half_width = DOCKING_ATOM_RADIUS / runtimeSP->docking_cell_width;
138
else atom_half_width = 0;
140
/* Auxilliary variable: */
141
if (runtimeSP->docking_cell_width != 0.0)
143
reciprocal_denominator = 1.0 / runtimeSP->docking_cell_width;
145
else reciprocal_denominator = 0.0;
147
/* Scan the macromolecular complex: */
148
for (atomI = 0; atomI < atomsN; atomI++)
150
/* Pointer to the current atom: */
151
curr_atomSP = curr_mol_complexSP->atomSP + atomI;
153
/* x and z coordinate of the current atom: */
154
x = curr_atomSP->raw_atomS.x[0];
155
z = curr_atomSP->raw_atomS.z[0];
157
/* y coordinate of the current atom: */
158
y = curr_atomSP->raw_atomS.y;
160
/* Coordinates relative to the upper left corner */
161
/* of the area which is covered by docking matrix: */
165
/* Matrix indices of the central point: row index depends on */
166
/* relative_x and column index depends on relative_z value: */
167
d = floor (relative_x * reciprocal_denominator);
168
central_rowI = (int) d;
169
d = floor (relative_z * reciprocal_denominator);
170
central_columnI = (int) d;
172
/* Scan the neighbourhood: */
173
row0I = central_rowI - atom_half_width;
174
row1I = central_rowI + atom_half_width;
175
column0I = central_columnI - atom_half_width;
176
column1I = central_columnI + atom_half_width;
177
for (rowI = row0I; rowI <= row1I; rowI++)
179
/* The allowed range is from 0 to matrix_width: */
180
if ((rowI < 0) || (rowI >= matrix_width)) continue;
182
for (columnI = column0I; columnI <= column1I; columnI++)
184
/* The allowed range is from 0 to matrix_width: */
185
if ((columnI < 0) || (columnI >= matrix_width)) continue;
187
/* Prepare the combined array index (the matrix is */
188
/* stored in the form of one-dimensional array): */
189
combinedI = rowI * matrix_width + columnI;
191
/* Prepare the pointer to the current cell: */
192
curr_cellP = exposed_atomIP + combinedI;
194
/* The index of the atom reffered by the stored atomic index: */
195
prev_atomI = *curr_cellP;
197
/* If some atomic index was stored to the cell defined by */
198
/* rowI and columnI, compare y coordinates of the atom */
199
/* reffered by this index and the current atom. For the */
200
/* bottom complex, the obscured atom has higher y, while */
201
/* for the top complex the obscured atom has lower y. */
204
/* The y coordinate of the atom reffered by stored index: */
205
old_y = (curr_mol_complexSP->atomSP + prev_atomI)->raw_atomS.y;
207
/* If projecting bottom complex: */
208
if (docking_complexI == 1)
210
if (old_y < y) continue;
213
/* If projecting top complex: */
216
if (old_y > y) continue;
220
/* If this point is reached, the current atom is not obscured. */
222
/* Store the index of the current atom to the matrix: */
228
/* Return positive value on success: */
232
/*===========================================================================*/