static PyObject *contacts(PyObject *self, PyObject *args) { int mol1, frame1, mol2, frame2; PyObject *selected1, *selected2; float cutoff; if (!PyArg_ParseTuple(args, (char *)"iiO!iiO!f:atomselection.contacts", &mol1, &frame1, &PyTuple_Type, &selected1, &mol2, &frame2, &PyTuple_Type, &selected2, &cutoff)) return NULL; VMDApp *app = get_vmdapp(); AtomSel *sel1 = sel_from_py(mol1, frame1, selected1, app); AtomSel *sel2 = sel_from_py(mol2, frame2, selected2, app); if (!sel1 || !sel2) { delete sel1; delete sel2; return NULL; } const float *ts1 = sel1->coordinates(app->moleculeList); const float *ts2 = sel2->coordinates(app->moleculeList); if (!ts1 || !ts2) { PyErr_SetString(PyExc_ValueError, "No coordinates in selection"); delete sel1; delete sel2; return NULL; } Molecule *mol = app->moleculeList->mol_from_id(mol1); GridSearchPair *pairlist = vmd_gridsearch3( ts1, sel1->num_atoms, sel1->on, ts2, sel2->num_atoms, sel2->on, cutoff, -1, (sel1->num_atoms + sel2->num_atoms) * 27); delete sel1; delete sel2; GridSearchPair *p, *tmp; PyObject *list1 = PyList_New(0); PyObject *list2 = PyList_New(0); for (p=pairlist; p != NULL; p=tmp) { // throw out pairs that are already bonded MolAtom *a1 = mol->atom(p->ind1); if (mol1 != mol2 || !a1->bonded(p->ind2)) { PyList_Append(list1, PyInt_FromLong(p->ind1)); PyList_Append(list2, PyInt_FromLong(p->ind2)); } tmp = p->next; free(p); } PyObject *result = PyList_New(2); PyList_SET_ITEM(result, 0, list1); PyList_SET_ITEM(result, 1, list2); return result; }
static PyObject *contacts(PyObject *self, PyObject *args) { int mol1, frame1, mol2, frame2; PyObject *selected1, *selected2; float cutoff; if (!PyArg_ParseTuple(args, (char *)"iiO!iiO!f:atomselection.contacts", &mol1, &frame1, &PyTuple_Type, &selected1, &mol2, &frame2, &PyTuple_Type, &selected2, &cutoff)) return NULL; VMDApp *app = get_vmdapp(); AtomSel *sel1 = sel_from_py(mol1, frame1, selected1, app); AtomSel *sel2 = sel_from_py(mol2, frame2, selected2, app); if (!sel1 || !sel2) { delete sel1; delete sel2; return NULL; } const float *ts1 = sel1->coordinates(app->moleculeList); const float *ts2 = sel2->coordinates(app->moleculeList); if (!ts1 || !ts2) { PyErr_SetString(PyExc_ValueError, "No coordinates in selection"); delete sel1; delete sel2; return NULL; } Molecule *mol = app->moleculeList->mol_from_id(mol1); GridSearchPair *pairlist = vmd_gridsearch3( ts1, sel1->num_atoms, sel1->on, ts2, sel2->num_atoms, sel2->on, cutoff, -1, (sel1->num_atoms + sel2->num_atoms) * 27); delete sel1; delete sel2; GridSearchPair *p, *tmp; PyObject *list1 = PyList_New(0); PyObject *list2 = PyList_New(0); PyObject *tmp1; PyObject *tmp2; for (p=pairlist; p != NULL; p=tmp) { // throw out pairs that are already bonded MolAtom *a1 = mol->atom(p->ind1); if (mol1 != mol2 || !a1->bonded(p->ind2)) { // Needed to avoid a memory leak. Append increments the refcount // of whatever gets added to it, but so does PyInt_FromLong. // Without a decref, the integers created never have their refcount // go to zero, and you leak memory. tmp1 = PyInt_FromLong(p->ind1); tmp2 = PyInt_FromLong(p->ind2); PyList_Append(list1, tmp1); PyList_Append(list2, tmp2); Py_DECREF(tmp1); Py_DECREF(tmp2); } tmp = p->next; free(p); } PyObject *result = PyList_New(2); PyList_SET_ITEM(result, 0, list1); PyList_SET_ITEM(result, 1, list2); return result; }