Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

py_measure.C

Go to the documentation of this file.
00001 /***************************************************************************
00002 *cr
00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the
00004 *cr University of Illinois
00005 *cr All Rights Reserved
00006 *cr
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010 * RCS INFORMATION:
00011 *
00012 * $RCSfile: py_measure.C,v $
00013 * $Author: johns $ $Locker: $ $State: Exp $
00014 * $Revision: 1.11 $ $Date: 2019年06月05日 14:50:54 $
00015 *
00016 ***************************************************************************
00017 * DESCRIPTION:
00018 * Code to measure atom distances, angles, dihedrals, etc.
00019 ***************************************************************************/
00020 
00021 #include "py_commands.h"
00022 #include "VMDApp.h"
00023 #include "Measure.h"
00024 
00025 static const char bond_doc[] =
00026 "Measures the distance between the atom1 and atom2 over the trajectory, either\n"
00027 "at the given frame or over frames from first to last. Distances between atoms\n"
00028 "in different molecules can be measured by giving specific molids\n\n"
00029 "Args:\n"
00030 " atom1 (int): Index of first atom\n"
00031 " atom2 (int): Index of second atom\n"
00032 " molid (int): Molecule ID of first atom, defaults to top molecule\n"
00033 " molid2 (int): Molecule ID of second atom, if different. (optional)\n"
00034 " frame (int): Measure distance in this single frame. Defaults to current\n"
00035 " first (int): For measuring multiple frames, first frame to measure\n"
00036 " last (int): For measuring multiple, last frame to measure\n"
00037 "Returns:\n"
00038 " (list of float): Distance between atoms for given frame(s)";
00039 static PyObject *py_measure_bond(PyObject *self, PyObject *args, PyObject *kwargs) {
00040 const char *kwlist[] = {"atom1", "atom2", "molid", "molid2", "frame", "first",
00041 "last", NULL};
00042 int first=-1, last=-1, frame=-1;
00043 PyObject *returnlist = NULL;
00044 int atmid[2], i;
00045 int molid[2] = {-1, -1};
00046 
00047 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|iiiii:measure.bond",
00048 (char**) kwlist, &atmid[0], &atmid[1],
00049 &molid[0], &molid[1], &frame, &first, &last))
00050 return NULL;
00051 
00052 VMDApp *app;
00053 if (!(app = get_vmdapp()))
00054 return NULL;
00055 
00056 // If molid(s) unset, use top molecule
00057 if (molid[0] == -1)
00058 molid[0] = app->molecule_top();
00059 
00060 if (molid[1] == -1)
00061 molid[1] = molid[0];
00062 
00063 // Need either (first, last) or a single frame.
00064 if (frame != -1 && (first != -1 || last != -1)) {
00065 PyErr_Warn(PyExc_SyntaxWarning, "frame as well as first or last were "
00066 "specified.\nReturning value for just the "
00067 "frame");
00068 first = -1;
00069 last = -1;
00070 }
00071 
00072 //Calculate the bond length
00073 ResizeArray<float> gValues(1024);
00074 int ret_val = measure_geom(app->moleculeList, molid, atmid, &gValues, frame,
00075 first, last, molid[0], MEASURE_BOND);
00076 if (ret_val < 0) {
00077 PyErr_SetString(PyExc_RuntimeError, measure_error(ret_val));
00078 return NULL;
00079 }
00080 
00081 // Build the list containing all measured distances
00082 int numvalues = gValues.num();
00083 if (!(returnlist = PyList_New(numvalues)))
00084 goto failure;
00085 
00086 for (i = 0; i < numvalues; i++) {
00087 PyList_SET_ITEM(returnlist, i, PyFloat_FromDouble(gValues[i]));
00088 
00089 // XXX this is inconsistent with the other two, why special?
00090 if (PyErr_Occurred())
00091 goto failure;
00092 }
00093 return returnlist;
00094 
00095 failure:
00096 PyErr_SetString(PyExc_ValueError, "Couldn't build list of distances");
00097 Py_XDECREF(returnlist);
00098 return NULL;
00099 }
00100 
00101 
00102 static const char angle_doc[] =
00103 "Measure angles between given atoms over a trajectory. Can specify multiple\n"
00104 "molids to measure angles between atoms in different molecules.\n\n"
00105 "Args:\n"
00106 " atom1 (int): Index of first atom\n"
00107 " atom2 (int): Index of second atom\n"
00108 " atom3 (int): Index of third atom\n"
00109 " molid (int): Molecule ID of first atom. Defaults to top molecule\n"
00110 " molid2 (int): Molecule ID of second atom, if different from first molid\n"
00111 " molid3 (int): Molecule ID of third atom, if different from first molid\n"
00112 " frame (int): Single frame to measure angle in. Defaults to current frame\n"
00113 " first (int): First frame in range to measure in, for multiple frames\n"
00114 " last (int): Last frame in range to measure in, for multiple frames\n"
00115 "Returns:\n"
00116 " (list of float): Angle as measured in frame(s)";
00117 static PyObject *py_measure_angle(PyObject *self, PyObject *args, PyObject *kwargs) {
00118 const char *kwlist[] = {"atom1", "atom2", "atom3", "molid", "molid2",
00119 "molid3", "frame", "first", "last", NULL};
00120 int first=-1, last=-1, frame=-1;
00121 int molid[3] = {-1, -1, -1};
00122 PyObject *returnlist;
00123 int atmid[3];
00124 
00125 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iii|iiiiii:measure.angle",
00126 (char**) kwlist, &atmid[0], &atmid[1],
00127 &atmid[2], &molid[0], &molid[1], &molid[2],
00128 &frame, &first, &last))
00129 return NULL;
00130 
00131 VMDApp *app;
00132 if (!(app = get_vmdapp()))
00133 return NULL;
00134 
00135 // Default to top molecule
00136 if (molid[0] == -1)
00137 molid[0] = app->molecule_top();
00138 
00139 // Other two molids default to the first molid
00140 if (molid[1] == -1)
00141 molid[1] = molid[0];
00142 
00143 if (molid[2] == -1)
00144 molid[2] = molid[0];
00145 
00146 // Warn if passing a single frame and a range
00147 if (frame != -1 && (first != -1 || last != -1)) {
00148 PyErr_Warn(PyExc_SyntaxWarning, "frame as well as first or last were "
00149 "specified.\nReturning value for just the "
00150 "frame");
00151 first = -1;
00152 last = -1;
00153 }
00154 //Calculate the angle
00155 ResizeArray<float> gValues(1024);
00156 int ret_val = measure_geom(app->moleculeList, molid, atmid, &gValues, frame,
00157 first, last, molid[0], MEASURE_ANGLE);
00158 if (ret_val < 0) {
00159 PyErr_SetString(PyExc_RuntimeError, measure_error(ret_val));
00160 return NULL;
00161 }
00162 
00163 //Build the python list.
00164 int numvalues = gValues.num();
00165 returnlist = PyList_New(numvalues);
00166 for (int i = 0; i < numvalues; i++)
00167 PyList_SetItem(returnlist, i, Py_BuildValue("f", gValues[i]));
00168 
00169 // Remove reference to list if something went wrong
00170 if (PyErr_Occurred()) {
00171 PyErr_SetString(PyExc_ValueError, "Couldn't build list of angles");
00172 Py_DECREF(returnlist);
00173 return NULL;
00174 }
00175 
00176 return returnlist;
00177 }
00178 
00179 
00180 static const char dihed_doc[] =
00181 "Measures the dihedral angle between atoms over the trajectory. Can specify\n"
00182 "multiple molecule IDs to measure over different loaded molecules.\n\n"
00183 "Args:\n"
00184 " atom1 (int): First atom in dihedral\n"
00185 " atom2 (int): Second atom in dihedral\n"
00186 " atom3 (int): Third atom in dihedral\n"
00187 " atom4 (int): Fourth atom in dihedral\n"
00188 " molid (int): Molecule ID to measure in. Defaults to top molecule\n"
00189 " molid2 (int): Molecule ID for second atom, if different from molid\n"
00190 " molid3 (int): Molecule ID for third atom, if different from molid\n"
00191 " molid4 (int): Molecule ID for fourth atom, if different from molid\n"
00192 " frame (int): Single frame to measure angle in. Defaults to current frame\n"
00193 " first (int): First frame in range to measure in, for multiple frames\n"
00194 " last (int): Last frame in range to measure in, for multiple frames\n"
00195 "Returns:\n"
00196 " (list of float): Dihedral as measured in frame(s)";
00197 static PyObject *py_measure_dihed(PyObject *self, PyObject *args, PyObject *kwargs) {
00198 const char *kwlist[] = {"atom1", "atom2", "atom3", "atom4", "molid", "molid2",
00199 "molid3", "molid4", "frame", "first", "last", NULL};
00200 int first=-1, last=-1, frame=-1;
00201 int molid[4] = {-1, -1, -1, -1};
00202 PyObject *returnlist;
00203 int atmid[4];
00204 
00205 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iiii|iiiiiii:measure.dihedral",
00206 (char**) kwlist, &atmid[0], &atmid[1],
00207 &atmid[2], &atmid[3], &molid[0], &molid[1],
00208 &molid[2], &molid[3], &frame, &first, &last))
00209 return NULL;
00210 
00211 VMDApp *app;
00212 if (!(app = get_vmdapp()))
00213 return NULL;
00214 
00215 // Molid defaults to top molecule
00216 if (molid[0] == -1)
00217 molid[0] = app->molecule_top();
00218 
00219 // Other molecule IDs default to molid
00220 if (molid[1] == -1)
00221 molid[1] = molid[0];
00222 
00223 if (molid[2] == -1)
00224 molid[2] = molid[0];
00225 
00226 if (molid[3] == -1)
00227 molid[3] = molid[0];
00228 
00229 // Warn if both frame and range of frames are given
00230 if (frame != -1 && (first != -1 || last != -1)) {
00231 PyErr_Warn(PyExc_SyntaxWarning, "frame as well as first or last were "
00232 "specified.\nReturning value for just the "
00233 "frame");
00234 first = -1;
00235 last = -1;
00236 }
00237 
00238 //Calculate the dihedral angle
00239 ResizeArray<float> gValues(1024);
00240 int ret_val = measure_geom(app->moleculeList, molid, atmid, &gValues, frame,
00241 first, last, molid[0], MEASURE_DIHED);
00242 if (ret_val < 0) {
00243 PyErr_SetString(PyExc_RuntimeError, measure_error(ret_val));
00244 return NULL;
00245 }
00246 
00247 //Build the python list.
00248 int numvalues = gValues.num();
00249 returnlist = PyList_New(numvalues);
00250 for (int i = 0; i < numvalues; i++)
00251 PyList_SetItem(returnlist, i, Py_BuildValue("f", gValues[i]));
00252 
00253 // Remove reference to list if something went wrong
00254 if (PyErr_Occurred()) {
00255 PyErr_SetString(PyExc_ValueError, "Couldn't build list of dihedrals");
00256 Py_DECREF(returnlist);
00257 return NULL;
00258 }
00259 
00260 return returnlist;
00261 }
00262 
00263 
00264 static PyMethodDef methods[] = {
00265 {"bond", (PyCFunction)py_measure_bond, METH_VARARGS | METH_KEYWORDS, bond_doc},
00266 {"angle", (PyCFunction)py_measure_angle, METH_VARARGS | METH_KEYWORDS, angle_doc},
00267 {"dihedral", (PyCFunction)py_measure_dihed, METH_VARARGS | METH_KEYWORDS, dihed_doc},
00268 {NULL, NULL}
00269 };
00270 
00271 
00272 static const char measure_moddoc[] =
00273 "Methods to measure bonds, angles, or dihedrals in loaded molecules";
00274 
00275 
00276 #if PY_MAJOR_VERSION >= 3
00277 static struct PyModuleDef measuredef = {
00278 PyModuleDef_HEAD_INIT,
00279 "measure",
00280 measure_moddoc,
00281 -1,
00282 methods,
00283 };
00284 #endif
00285 
00286 
00287 PyObject* initmeasure() {
00288 #if PY_MAJOR_VERSION >= 3
00289 PyObject *m = PyModule_Create(&measuredef);
00290 #else
00291 PyObject *m = Py_InitModule3("measure", methods, measure_moddoc);
00292 #endif
00293 return m;
00294 }

Generated on Tue Nov 18 02:47:58 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /