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;
}
/*===========================================================================*/
|