Skip to content

Commit f9ce688

Browse files
committed
Return receptor and ligand interfaces from cpydock scoring function
1 parent 009a08f commit f9ce688

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

lightdock/scoring/cpydock/driver.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,13 @@ def __call__(self, receptor, receptor_coordinates, ligand, ligand_coordinates):
119119
"""Computes the pyDock scoring energy using receptor and ligand which are
120120
instances of DockinModel.
121121
"""
122-
elec, vdw, solv_rec, solv_lig = cpydock.calculate_energy(receptor_coordinates, ligand_coordinates,
123-
receptor.charges, ligand.charges,
124-
receptor.vdw_energy, ligand.vdw_energy,
125-
receptor.vdw_radii, ligand.vdw_radii,
126-
receptor.hydrogens, ligand.hydrogens,
127-
receptor.sasa, ligand.sasa,
128-
receptor.des_energy, ligand.des_energy)
122+
elec, vdw, solv_rec, solv_lig, interface_receptor, interface_ligand = cpydock.calculate_energy(receptor_coordinates, ligand_coordinates,
123+
receptor.charges, ligand.charges,
124+
receptor.vdw_energy, ligand.vdw_energy,
125+
receptor.vdw_radii, ligand.vdw_radii,
126+
receptor.hydrogens, ligand.hydrogens,
127+
receptor.sasa, ligand.sasa,
128+
receptor.des_energy, ligand.des_energy)
129129
solv = -1*(solv_rec + solv_lig)
130130
return (elec + parameters.scoring_vdw_weight * vdw + solv)*-1.
131131

lightdock/scoring/cpydock/energy/c/cpydock.c

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,27 @@ static PyObject * cpydock_calculate_energy(PyObject *self, PyObject *args) {
2828
PyArrayObject *rec_charges, *lig_charges, *rec_vdw, *lig_vdw, *rec_vdw_radii, *lig_vdw_radii = NULL;
2929
PyArrayObject *rec_hydrogens, *lig_hydrogens, *rec_asa, *lig_asa, *rec_des_energy, *lig_des_energy = NULL;
3030
double atom_elec, total_elec, total_vdw, total_solvation_rec, total_solvation_lig, vdw_energy, vdw_radius, p6, k, solv_rec, solv_lig;
31-
unsigned int rec_len, lig_len, i, j;
32-
double **rec_array, **lig_array, x, y, z, distance2;
31+
unsigned int rec_len, lig_len, i, j, interface_len, *interface_receptor, *interface_ligand;
32+
double **rec_array, **lig_array, x, y, z, distance2, interface_cutoff;
3333
npy_intp dims[2];
34-
PyArray_Descr *descr;
3534
double *rec_c_charges, *lig_c_charges, *rec_c_vdw, *lig_c_vdw, *rec_c_vdw_radii, *lig_c_vdw_radii = NULL;
3635
double *rec_c_asa, *lig_c_asa, *rec_c_des_energy, *lig_c_des_energy = NULL;
3736
unsigned int *rec_c_hydrogens, *lig_c_hydrogens = NULL;
3837
double *min_rec_distance, *min_lig_distance = NULL;
39-
PyObject *result = PyTuple_New(4);
38+
PyObject *result = PyTuple_New(6);
4039

4140
total_elec = 0.0;
4241
atom_elec = 0.0;
4342
total_vdw = 0.0;
4443
total_solvation_rec = 0.0;
4544
total_solvation_lig = 0.0;
45+
interface_cutoff = 3.9;
46+
interface_len = 0;
4647

47-
if (PyArg_ParseTuple(args, "OOOOOOOOOOOOOO",
48+
if (PyArg_ParseTuple(args, "OOOOOOOOOOOOOO|d",
4849
&receptor_coordinates, &ligand_coordinates, &rec_charges, &lig_charges,
4950
&rec_vdw, &lig_vdw, &rec_vdw_radii, &lig_vdw_radii, &rec_hydrogens, &lig_hydrogens,
50-
&rec_asa, &lig_asa, &rec_des_energy, &lig_des_energy)) {
51-
52-
descr = PyArray_DescrFromType(NPY_DOUBLE);
51+
&rec_asa, &lig_asa, &rec_des_energy, &lig_des_energy, interface_cutoff)) {
5352

5453
tmp0 = PyObject_GetAttrString(receptor_coordinates, "coordinates");
5554
tmp1 = PyObject_GetAttrString(ligand_coordinates, "coordinates");
@@ -59,10 +58,10 @@ static PyObject * cpydock_calculate_energy(PyObject *self, PyObject *args) {
5958

6059
dims[1] = 3;
6160
dims[0] = rec_len;
62-
PyArray_AsCArray((PyObject **)&tmp0, (void **)&rec_array, dims, 2, descr);
61+
PyArray_AsCArray((PyObject **)&tmp0, (void **)&rec_array, dims, 2, PyArray_DescrFromType(NPY_DOUBLE));
6362

6463
dims[0] = lig_len;
65-
PyArray_AsCArray((PyObject **)&tmp1, (void **)&lig_array, dims, 2, descr);
64+
PyArray_AsCArray((PyObject **)&tmp1, (void **)&lig_array, dims, 2, PyArray_DescrFromType(NPY_DOUBLE));
6665

6766
// Get pointers to the Python array structures
6867
rec_c_charges = PyArray_GETPTR1(rec_charges, 0);
@@ -81,6 +80,8 @@ static PyObject * cpydock_calculate_energy(PyObject *self, PyObject *args) {
8180
// Structures to store the atom at minimal distance of a given atom
8281
min_rec_distance = malloc(rec_len*sizeof(double));
8382
min_lig_distance = malloc(lig_len*sizeof(double));
83+
interface_receptor = malloc(lig_len*sizeof(unsigned int));
84+
interface_ligand = malloc(lig_len*sizeof(unsigned int));
8485
for (i = 0; i < rec_len; i++) min_rec_distance[i] = HUGE_DISTANCE;
8586
for (j = 0; j < lig_len; j++) min_lig_distance[j] = HUGE_DISTANCE;
8687

@@ -109,14 +110,25 @@ static PyObject * cpydock_calculate_energy(PyObject *self, PyObject *args) {
109110
}
110111

111112
// Van der Waals energy
112-
if (distance2 <= VDW_DIST_CUTOFF2){
113+
if (distance2 <= VDW_DIST_CUTOFF2) {
113114
vdw_energy = sqrt(rec_c_vdw[i] * lig_c_vdw[j]);
114115
vdw_radius = rec_c_vdw_radii[i] + lig_c_vdw_radii[j];
115116
p6 = pow(vdw_radius, 6) / pow(distance2, 3);
116117
k = vdw_energy * (p6*p6 - 2.0 * p6);
117118
if (k > VDW_CUTOFF) k = VDW_CUTOFF;
118119
total_vdw += k;
119120
}
121+
122+
if (sqrt(distance2) <= interface_cutoff) {
123+
interface_receptor[interface_len] = i;
124+
interface_ligand[interface_len++] = j;
125+
}
126+
127+
}
128+
129+
if (!(interface_len%lig_len)) {
130+
interface_receptor = realloc(interface_receptor, (interface_len/lig_len + 1)*lig_len*sizeof(unsigned int));
131+
interface_ligand = realloc(interface_ligand, (interface_len/lig_len + 1)*lig_len*sizeof(unsigned int));
120132
}
121133
}
122134
// Convert total electrostatics to Kcal/mol:
@@ -146,18 +158,23 @@ static PyObject * cpydock_calculate_energy(PyObject *self, PyObject *args) {
146158
// Free structures
147159
PyArray_Free(tmp0, rec_array);
148160
PyArray_Free(tmp1, lig_array);
149-
Py_DECREF(descr);
150161
Py_DECREF(tmp0);
151162
Py_DECREF(tmp1);
152163
free(min_rec_distance);
153164
free(min_lig_distance);
154165
}
155166

167+
interface_receptor = realloc(interface_receptor, interface_len*sizeof(unsigned int));
168+
interface_ligand = realloc(interface_ligand, interface_len*sizeof(unsigned int));
169+
dims[0] = interface_len;
170+
156171
// Return a tuple with the following values for calculated energies:
157172
PyTuple_SetItem(result, 0, PyFloat_FromDouble(total_elec));
158173
PyTuple_SetItem(result, 1, PyFloat_FromDouble(total_vdw));
159174
PyTuple_SetItem(result, 2, PyFloat_FromDouble(total_solvation_rec));
160175
PyTuple_SetItem(result, 3, PyFloat_FromDouble(total_solvation_lig));
176+
PyTuple_SetItem(result, 4, PyArray_SimpleNewFromData(1, dims, NPY_UINT, interface_receptor));
177+
PyTuple_SetItem(result, 5, PyArray_SimpleNewFromData(1, dims, NPY_UINT, interface_ligand));
161178
return result;
162179
}
163180

0 commit comments

Comments
 (0)