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

py_topo.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_topo.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.10 $       $Date: 2019/05/31 07:07:48 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   Query and manipulate molecular topology information
00019  ***************************************************************************/
00020 
00021 #include "py_commands.h"
00022 #include "VMDApp.h"
00023 #include "Molecule.h"
00024 #include "MoleculeList.h"
00025 #include "DrawMolecule.h"
00026 
00027 static const char bond_doc[] = "Get all unique bonds within a specified molecule. Optionally, can get bond\n"
00028 "type and order by modifying the type parameter\n\n"
00029 "Args:\n"
00030 "    molid (int): Molecule ID to query. Defaults to top molecule\n"
00031 "    type (bool): Whether to include bond type information in the result\n"
00032 "        Defaults to False.\n"
00033 "    orders (bool): Whether to include bond order information in the result\n"
00034 "        Defaults to False.\n"
00035 "Returns:\n"
00036 "    (list of lists) Information about each bond in the system. Each bond\n"
00037 "        will be a list with the indices of the two atoms in the\n"
00038 "        bond, followed by bond type (as a string) and order (as a float) if\n"
00039 "        requested";
00040 static PyObject* topo_get_bond(PyObject *self, PyObject *args, PyObject *kwargs) {
00041   const char *kwlist[] = {"molid", "type", "order", NULL};
00042   PyObject *returnlist = NULL, *bond = NULL;
00043   int b_types = 0, b_orders = 0, molid = -1;
00044   PyObject *obtypes = Py_False;
00045   int i, j, types;
00046   Molecule *mol;
00047 
00048   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOO&:topology.bonds",
00049                                      (char**) kwlist, &molid, &obtypes,
00050                                      convert_bool, &b_orders))
00051     return NULL;
00052 
00053   VMDApp *app;
00054   if (!(app = get_vmdapp()))
00055     return NULL;
00056 
00057   // Check molid is valid
00058   if (molid == -1)
00059     molid = app->molecule_top();
00060 
00061   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00062     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00063     return NULL;
00064   }
00065 
00066   if (PyBool_Check(obtypes)) {
00067     b_types = (obtypes == Py_True) ? 1 : 0;
00068 
00069   // Handle deprecated types argument
00070   } else if (is_pyint(obtypes)) {
00071     // Check regular argument wasn't also passed
00072     if (kwargs && PyDict_GetItemString(kwargs, "order")) {
00073       PyErr_SetString(PyExc_ValueError, "Cannot specify deprecated type "
00074                       "argument with new or orders arguments");
00075       return NULL;
00076     }
00077     types = as_int(obtypes);
00078 
00079     if (types == 3)
00080       b_types = b_orders = 1;
00081     else if (types == 2)
00082       b_orders = 1;
00083     else if (types == 1)
00084       b_types = 1;
00085 
00086     PyErr_Warn(PyExc_DeprecationWarning, "type int keyword is now replaced by "
00087                "type and order booleans");
00088   // Handle error if it's not a boolean
00089   } else {
00090     PyErr_SetString(PyExc_TypeError, "type keyword expected a bool");
00091     return NULL;
00092   }
00093 
00094   // Assume no bonds, and build the list from empty to avoid traversing
00095   // the entire bond list twice
00096   if (!(returnlist = PyList_New(0)))
00097     goto failure;
00098 
00099   for (i = 0; i < mol->nAtoms - 1; i++) { // Last atom can add no new bonds.
00100     const MolAtom *atom = mol->atom(i);
00101     for (j = 0; j < atom->bonds; j++) {
00102       if (i < atom->bondTo[j]) {
00103         if (b_types && b_orders) {
00104           bond = Py_BuildValue("iisf", i, atom->bondTo[j],
00105                                mol->bondTypeNames.name(mol->getbondtype(i, j)),
00106                                mol->getbondorder(i, j));
00107         } else if (b_types) {
00108           bond = Py_BuildValue("iis", i, atom->bondTo[j],
00109                                mol->bondTypeNames.name(mol->getbondtype(i, j)));
00110         } else if (b_orders) {
00111           bond = Py_BuildValue("iif", i, atom->bondTo[j],
00112                                mol->getbondorder(i, j));
00113         } else {
00114           bond = Py_BuildValue("ii", i, atom->bondTo[j]);
00115         }
00116 
00117         // Don't leak references with PyList_Append
00118         PyList_Append(returnlist, bond);
00119         Py_XDECREF(bond);
00120         if (PyErr_Occurred())
00121           goto failure;
00122       }
00123     }
00124   }
00125   return returnlist;
00126 
00127 failure:
00128   PyErr_SetString(PyExc_RuntimeError, "problem building bond list");
00129   Py_XDECREF(returnlist);
00130   return NULL;
00131 }
00132 
00133 
00134 static const char angle_doc[] =
00135 "Get all unique angles within a specified molecule. Optionally, can get angle\n"
00136 "type as well\n\n"
00137 "Args:\n"
00138 "    molid (int): Molecule ID to query. Defaults to top molecule\n"
00139 "    type (bool): Whether to include angle type information in the result\n"
00140 "        Defaults to False.\n"
00141 "Returns:\n"
00142 "    (list of lists) Information about each angle in the system. Each angle \n"
00143 "        will be a list with the indices of the three atoms comprising the\n"
00144 "        angle, followed by angle type (as a string) if requested.";
00145 static PyObject* topo_get_angle(PyObject *self, PyObject *args,
00146                                 PyObject *kwargs) {
00147   const char *kwlist[] = {"molid", "type", NULL};
00148   PyObject *returnlist = NULL;
00149   int molid = -1, types = 0;
00150   Molecule *mol;
00151   int i;
00152 
00153   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:topology.angle",
00154                                    (char**) kwlist, &molid, &types))
00155     return NULL;
00156 
00157   VMDApp *app;
00158   if (!(app = get_vmdapp()))
00159     return NULL;
00160 
00161   if (molid == -1)
00162     molid = app->molecule_top();
00163 
00164   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00165     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00166     return NULL;
00167   }
00168 
00169   if (!(returnlist = PyList_New(mol->num_angles())))
00170     goto failure;
00171 
00172   for (i=0; i<mol->num_angles(); i++) {
00173     PyObject* angle;
00174     if (types) {
00175       angle = Py_BuildValue("iiis", mol->angles[3*i], mol->angles[3*i+1],
00176                             mol->angles[3*i+2],
00177                             mol->angleTypeNames.name(mol->get_angletype(i)));
00178     } else {
00179       angle = Py_BuildValue("iii", mol->angles[3*i], mol->angles[3*i+1],
00180                             mol->angles[3*i+2]);
00181     }
00182     PyList_SET_ITEM(returnlist, i, angle);
00183     if (PyErr_Occurred())
00184       goto failure;
00185   }
00186   return returnlist;
00187 
00188 failure:
00189   PyErr_SetString(PyExc_RuntimeError, "problem building angle list");
00190   Py_XDECREF(returnlist);
00191   return NULL;
00192 }
00193 
00194 
00195 static const char dihed_doc[] =
00196 "Get all unique dihedrals within a specified molecule. Optionally, can get\n"
00197 "dihedral type as well\n\n"
00198 "Args:\n"
00199 "    molid (int): Molecule ID to query. Defaults to top molecule\n"
00200 "    type (bool): Whether to include dihedral type information in the result\n"
00201 "        Defaults to False.\n"
00202 "Returns:\n"
00203 "    (list of lists) Information about each dihedral in the system. Each\n"
00204 "        dihedral will be a list with the indices of the four atoms\n"
00205 "        comprising the dihedral, followed by dihedral type (as a string) if\n"
00206 "        requested.";
00207 static PyObject* topo_get_dihed(PyObject *self, PyObject *args,
00208                                 PyObject *kwargs) {
00209   const char *kwlist[] = {"molid", "type", NULL};
00210   PyObject *returnlist = NULL;
00211   int molid = -1, types = 0;
00212   Molecule *mol;
00213   int i;
00214 
00215   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:topology.dihedral",
00216                                    (char**) kwlist, &molid, &types))
00217         return NULL;
00218 
00219   VMDApp *app;
00220   if (!(app = get_vmdapp()))
00221     return NULL;
00222 
00223   if (molid == -1)
00224     molid = app->molecule_top();
00225 
00226   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00227     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00228     return NULL;
00229   }
00230 
00231   if (!(returnlist = PyList_New(mol->num_dihedrals())))
00232     goto failure;
00233 
00234   for (i = 0; i < mol->num_dihedrals(); i++) {
00235     PyObject* dihed;
00236     if (types) {
00237       dihed = Py_BuildValue("iiiis",
00238                             mol->dihedrals[4*i], mol->dihedrals[4*i+1],
00239                             mol->dihedrals[4*i+2], mol->dihedrals[4*i+3],
00240                             mol->dihedralTypeNames.name(mol->get_dihedraltype(i)));
00241     } else {
00242       dihed = Py_BuildValue("iiii",
00243                             mol->dihedrals[4*i], mol->dihedrals[4*i+1],
00244                             mol->dihedrals[4*i+2], mol->dihedrals[4*i+3]);
00245     }
00246     PyList_SET_ITEM(returnlist, i, dihed);
00247     if (PyErr_Occurred())
00248       goto failure;
00249   }
00250   return returnlist;
00251 
00252 failure:
00253   PyErr_SetString(PyExc_RuntimeError, "Problem building dihedral list");
00254   Py_XDECREF(returnlist);
00255   return NULL;
00256 }
00257 
00258 
00259 static const char impropers_doc[] =
00260 "Get all unique impropers within a specified molecule. Optionally, can get\n"
00261 "improper type as well\n\n"
00262 "Args:\n"
00263 "    molid (int): Molecule ID to query. Defaults to top molecule\n"
00264 "    type (bool): Whether to include improper type information in the result\n"
00265 "        Defaults to False.\n"
00266 "Returns:\n"
00267 "    (list of lists) Information about each improper in the system. Each\n"
00268 "        improper will be a list with the indices of the four atoms\n"
00269 "        comprising the improper, followed by improper type (as a string) if\n"
00270 "        requested.";
00271 static PyObject* topo_get_impro(PyObject *self, PyObject *args,
00272                                 PyObject *kwargs) {
00273   const char *kwlist[] = {"molid", "type", NULL};
00274   PyObject *returnlist = NULL;
00275   int molid = -1, types = 0;
00276   Molecule *mol;
00277   int i;
00278 
00279   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:topology.impropers",
00280                                    (char**) kwlist, &molid, &types))
00281     return NULL;
00282 
00283   VMDApp *app;
00284   if (!(app = get_vmdapp()))
00285     return NULL;
00286 
00287   if (molid == -1)
00288     molid = app->molecule_top();
00289 
00290   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00291     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00292     return NULL;
00293   }
00294 
00295   if (!(returnlist = PyList_New(mol->num_impropers())))
00296     goto failure;
00297 
00298   for (i = 0; i < mol->num_impropers(); i++) {
00299     PyObject* improper;
00300     if (types) {
00301       improper = Py_BuildValue("iiiis",
00302                                mol->impropers[4*i], mol->impropers[4*i+1],
00303                                mol->impropers[4*i+2], mol->impropers[4*i+3],
00304                                mol->improperTypeNames.name(mol->get_impropertype(i)));
00305     } else {
00306       improper = Py_BuildValue("iiii",
00307                                mol->impropers[4*i], mol->impropers[4*i+1],
00308                                mol->impropers[4*i+2], mol->impropers[4*i+3]);
00309     }
00310     PyList_SetItem(returnlist, i, improper);
00311   }
00312   return returnlist;
00313 
00314 failure:
00315   PyErr_SetString(PyExc_RuntimeError, "Problem building improper list");
00316   Py_XDECREF(returnlist);
00317   return NULL;
00318 }
00319 
00320 
00321 static const char addbond_doc[] =
00322 "Add a bond between two atoms with given indices. If bond is already present,\n"
00323 "nothing will be done.\n\n"
00324 "Args:\n"
00325 "    i (int): Index of first atom\n"
00326 "    j (int): Index of second atom\n"
00327 "    molid (int): Molecule ID to add bond to. Defaults to top molecule.\n"
00328 "    order (float): Bond order. Defaults to 1.0\n"
00329 "    type (str): Bond type. Can be from output of `topology.bondtypes()`,\n"
00330 "        or can define a new bond type. Defaults to None";
00331 static PyObject* topo_add_bond(PyObject *self, PyObject *args, PyObject *kwargs) {
00332   const char *kwlist[] = {"i", "j", "molid", "order", "type", NULL};
00333   int molid = -1, type = -1;
00334   char *bondtype = NULL;
00335   float order = 1.0;
00336   Molecule *mol;
00337   int i, j;
00338 
00339   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|ifz:topology.addbond",
00340                                    (char**) kwlist, &i, &j, &molid, &order,
00341                                    &bondtype))
00342     return NULL;
00343 
00344   VMDApp *app;
00345   if (!(app = get_vmdapp()))
00346     return NULL;
00347 
00348   if (molid == -1)
00349     molid = app->molecule_top();
00350 
00351   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00352     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00353     return NULL;
00354   }
00355 
00356   // Handle bond type
00357   if (bondtype) {
00358     type = mol->bondTypeNames.add_name(bondtype, 0);
00359     mol->set_dataset_flag(BaseMolecule::BONDTYPES);
00360   }
00361 
00362   mol->set_dataset_flag(BaseMolecule::BONDS);
00363   mol->set_dataset_flag(BaseMolecule::BONDORDERS);
00364 
00365   if (mol->add_bond_dupcheck(i, j, order, type)) {
00366     PyErr_Format(PyExc_RuntimeError, "Problem adding bond between atoms %d "
00367                  "and %d on molid %d", i, j, molid);
00368     return NULL;
00369   }
00370 
00371   Py_INCREF(Py_None);
00372   return Py_None;
00373 }
00374 
00375 
00376 static const char addangle_doc[] =
00377 "Add an angle between three atoms with given indices. No checking for\n"
00378 "duplicate angles is performed\n\n"
00379 "Args:\n"
00380 "    i (int): Index of first atom\n"
00381 "    j (int): Index of second atom\n"
00382 "    k (int): Index of third atom\n"
00383 "    molid (int): Molecule ID to add angle to. Defaults to top molecule.\n"
00384 "    type (str): Angle type. Can be from output of `topology.getangletypes()`,\n"
00385 "        or can define a new angle type. Defaults to None\n"
00386 "Returns:\n"
00387 "    (int) Index of new angle in system";
00388 static PyObject* topo_add_angle(PyObject *self, PyObject *args,
00389                                 PyObject *kwargs) {
00390   const char *kwlist[] = {"i", "j", "k", "molid", "type", NULL};
00391   int molid = -1, type = -1;
00392   char *angletype = NULL;
00393   Molecule *mol;
00394   int i, j, k;
00395 
00396   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iii|iz:topology.addangle",
00397                                    (char**) kwlist, &i, &j, &k, &molid,
00398                                    &angletype))
00399     return NULL;
00400 
00401   VMDApp *app;
00402   if (!(app = get_vmdapp()))
00403     return NULL;
00404 
00405   if (molid == -1)
00406     molid = app->molecule_top();
00407 
00408   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00409     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00410     return NULL;
00411   }
00412 
00413   if (angletype) {
00414     type = mol->angleTypeNames.add_name(angletype, 0);
00415     // This is indirectly set in add_angle, but do it explictly to be clear
00416     mol->set_dataset_flag(BaseMolecule::ANGLETYPES);
00417   }
00418   mol->set_dataset_flag(BaseMolecule::ANGLES);
00419 
00420   return as_pyint(mol->add_angle(i, j, k, type));
00421 }
00422 
00423 
00424 static const char adddihed_doc[] =
00425 "Add a dihedral between four atoms with the given indices. No checking for\n"
00426 "duplicate dihedrals is performed.\n\n"
00427 "Args:\n"
00428 "    i (int): Index of first atom\n"
00429 "    j (int): Index of second atom\n"
00430 "    k (int): Index of third atom\n"
00431 "    l (int): Index of fourth atom\n"
00432 "    molid (int): Molecule ID to add dihedral in. Defaults to top molecule.\n"
00433 "    type (str): Angle type. Can be from output of `topology.getangletypes()`,\n"
00434 "        or can define a new angle type. Defaults to None\n"
00435 "Returns:\n"
00436 "    (int) New number of dihedrals defined in system";
00437 static PyObject* topo_add_dihed(PyObject *self, PyObject *args,
00438                                 PyObject *kwargs) {
00439   const char *kwlist[] = {"i", "j", "k", "l", "molid", "type", NULL};
00440   int molid = -1, type = -1;
00441   char *dihetype = NULL;
00442   int i, j, k, l;
00443   Molecule *mol;
00444 
00445   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iiii|iz:topology.adddihedral",
00446                                    (char**) kwlist, &i, &j, &k, &l, &molid,
00447                                    &dihetype))
00448     return NULL;
00449 
00450   VMDApp *app;
00451   if (!(app = get_vmdapp()))
00452     return NULL;
00453 
00454   if (molid == -1)
00455     molid = app->molecule_top();
00456 
00457   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00458     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00459     return NULL;
00460   }
00461 
00462   if (dihetype) {
00463     type = mol->dihedralTypeNames.add_name(dihetype, 0);
00464     // This is indirectly set in add_dihedral, but do it explictly to be clear
00465     // Yes, it is supposed to be the ANGLETYPES flag
00466     mol->set_dataset_flag(BaseMolecule::ANGLETYPES);
00467   }
00468   mol->set_dataset_flag(BaseMolecule::ANGLES);
00469 
00470   return as_pyint(mol->add_dihedral(i, j, k, l, type));
00471 }
00472 
00473 
00474 static const char addimproper_doc[] =
00475 "Add an improper dihedral between four atoms with the given indices. No\n"
00476 "checking for duplicate impropers is performed.\n\n"
00477 "Args:\n"
00478 "    i (int): Index of first atom\n"
00479 "    j (int): Index of second atom\n"
00480 "    k (int): Index of third atom\n"
00481 "    l (int): Index of fourth atom\n"
00482 "    molid (int): Molecule ID to add dihedral in. Defaults to top molecule.\n"
00483 "    type (str): Angle type. Can be from output of `topology.getangletypes()`,\n"
00484 "        or can define a new angle type. Defaults to None\n"
00485 "Returns:\n"
00486 "    (int) New number of improper dihedrals defined in system";
00487 static PyObject* topo_add_improp(PyObject *self, PyObject *args,
00488                                  PyObject *kwargs) {
00489   const char *kwlist[] = {"i", "j", "k", "l", "molid", "type", NULL};
00490   int molid = -1, type = -1;
00491   char *dihetype = NULL;
00492   int i, j, k, l;
00493   Molecule *mol;
00494 
00495   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iiii|iz:topology.addimproper",
00496                                    (char**) kwlist, &i, &j, &k, &l, &molid,
00497                                    &dihetype))
00498     return NULL;
00499 
00500   VMDApp *app;
00501   if (!(app = get_vmdapp()))
00502     return NULL;
00503 
00504   if (molid == -1)
00505     molid = app->molecule_top();
00506 
00507   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00508     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00509     return NULL;
00510   }
00511 
00512   if (dihetype) {
00513     type = mol->improperTypeNames.add_name(dihetype, 0);
00514     // This is indirectly set in add_dihedral, but do it explictly to be clear
00515     // Yes, it is supposed to be the ANGLETYPES flag
00516     mol->set_dataset_flag(BaseMolecule::ANGLETYPES);
00517   }
00518   mol->set_dataset_flag(BaseMolecule::ANGLES);
00519 
00520   return as_pyint(mol->add_improper(i, j, k, l, type));
00521 }
00522 
00523 
00524 static const char delbond_doc[] =
00525 "Delete a bond between atoms with the given indices. If the bond does not\n"
00526 "exist, does nothing.\n\n"
00527 "Args:\n"
00528 "    i (int): Index of first atom\n"
00529 "    j (int): Index of second atom\n"
00530 "    molid (int): Molecule ID to delete bond from. Defaults to top molecule.\n"
00531 "Returns:\n"
00532 "    (bool) True if bond exists and was deleted";
00533 static PyObject* topo_del_bond(PyObject *self, PyObject *args, PyObject *kwargs) {
00534   const char *kwlist[] = {"i", "j", "molid", NULL};
00535   PyObject *result = Py_False;
00536   MolAtom *atomi, *atomj;
00537   float *bondOrders;
00538   int molid = -1;
00539   int *bondTypes;
00540   Molecule *mol;
00541   int i, j, tmp;
00542 
00543   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:topology.delbond",
00544                                    (char**) kwlist, &i, &j, &molid))
00545     return NULL;
00546 
00547   VMDApp *app;
00548   if (!(app = get_vmdapp()))
00549     return NULL;
00550 
00551   if (molid == -1)
00552     molid = app->molecule_top();
00553 
00554   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00555     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00556     return NULL;
00557   }
00558 
00559   if (i < 0 || j < 0 || i >= mol->nAtoms || j >= mol->nAtoms) {
00560     PyErr_Format(PyExc_ValueError, "invalid bond atom indices '%d'-'%d'", i, j);
00561     return NULL;
00562   }
00563 
00564   bondOrders = mol->extraflt.data("bondorders");
00565   bondTypes = mol->extraint.data("bondtypes");
00566   atomi = mol->atom(i);
00567   atomj = mol->atom(j);
00568 
00569   for (tmp = 0; tmp < atomi->bonds && j != atomi->bondTo[tmp]; tmp++);
00570 
00571   // Match is found
00572   if (tmp < atomi->bonds) {
00573     atomi->bondTo[tmp] = atomi->bondTo[--atomi->bonds];
00574     mol->set_dataset_flag(BaseMolecule::BONDS);
00575 
00576     if (bondOrders) {
00577       bondOrders[i * MAXATOMBONDS + tmp] = bondOrders[i * MAXATOMBONDS + atomi->bonds];
00578       bondOrders[i * MAXATOMBONDS + atomi->bonds] = 1.0;
00579       mol->set_dataset_flag(BaseMolecule::BONDORDERS);
00580     }
00581 
00582     if (bondTypes) {
00583       bondTypes[i * MAXATOMBONDS + tmp] = bondTypes[i * MAXATOMBONDS + atomi->bonds];
00584       bondTypes[i * MAXATOMBONDS + atomi->bonds] = -1;
00585       mol->set_dataset_flag(BaseMolecule::BONDTYPES);
00586     }
00587 
00588     for (tmp = 0; tmp < atomj->bonds && i != atomj->bondTo[tmp]; tmp++);
00589     atomj->bondTo[tmp] = atomj->bondTo[--atomj->bonds];
00590 
00591     result = Py_True;
00592   }
00593 
00594   Py_INCREF(result);
00595   return result;
00596 }
00597 
00598 
00599 static const char delangle_doc[] =
00600 "Delete an angle between atoms with the given indices. If the angle does not\n"
00601 "exist, does nothing.\n\n"
00602 "Args:\n"
00603 "    i (int): Index of first atom\n"
00604 "    j (int): Index of second atom\n"
00605 "    k (int): Index of third atom\n"
00606 "    molid (int): Molecule ID to delete from. Defaults to top molecule.\n"
00607 "Returns:\n"
00608 "    (bool) True if angle exists and was deleted";
00609 static PyObject* topo_del_angle(PyObject *self, PyObject *args,
00610                                 PyObject *kwargs) {
00611   const char *kwlist[] = {"i", "j", "k", "molid", NULL};
00612   PyObject *result = Py_False;
00613   int molid = -1;
00614   int i, j, k, s;
00615   Molecule *mol;
00616 
00617   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iii|i:topology:delangle",
00618                                    (char**) kwlist, &i, &j, &k, &molid))
00619     return NULL;
00620 
00621   VMDApp *app;
00622   if (!(app = get_vmdapp()))
00623     return NULL;
00624 
00625   if (molid == -1)
00626     molid = app->molecule_top();
00627 
00628   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00629     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00630     return NULL;
00631   }
00632 
00633   if (i < 0 || j < 0 || k < 0 || 
00634       k >= mol->nAtoms || i >= mol->nAtoms || j >= mol->nAtoms) {
00635     PyErr_Format(PyExc_ValueError, "invalid angle atom indices %d-%d-%d",
00636                  i, j, k);
00637     return NULL;
00638   }
00639 
00640   // Reorder so i < k to follow convention for atom ordering in angles
00641   if (i > k) {
00642     s = k;
00643     k = i;
00644     i = s;
00645   }
00646 
00647   s = mol->num_angles();
00648   for (int tmp = 0; tmp < s; tmp++) {
00649     if (i == mol->angles[3*tmp  ] && 
00650         j == mol->angles[3*tmp+1] && 
00651         k == mol->angles[3*tmp+2]) {
00652       mol->angles[3*tmp  ] = mol->angles[3*s-3];
00653       mol->angles[3*tmp+1] = mol->angles[3*s-2];
00654       mol->angles[3*tmp+2] = mol->angles[3*s-1];
00655 
00656       if (mol->angleTypes.num() > tmp) {
00657         if (mol->angleTypes.num() == s)
00658           mol->angleTypes[tmp] = mol->angleTypes[s-1];
00659         else
00660           mol->angleTypes[tmp] = -1;
00661       }
00662 
00663       mol->angles.pop();
00664       mol->angles.pop();
00665       mol->angles.pop();
00666       mol->set_dataset_flag(BaseMolecule::ANGLES);
00667       result = Py_True;
00668       break;
00669     }
00670   }
00671 
00672   Py_INCREF(result);
00673   return result;
00674 }
00675 
00676 
00677 static const char deldihed_doc[] =
00678 "Delete a dihedral angle between atoms with the given indices. If the\n"
00679 "dihedral does not exist, does nothing.\n\n"
00680 "Args:\n"
00681 "    i (int): Index of first atom\n"
00682 "    j (int): Index of second atom\n"
00683 "    k (int): Index of third atom\n"
00684 "    l (int): Index of fourth atom\n"
00685 "    molid (int): Molecule ID to delete from. Defaults to top molecule.\n"
00686 "Returns:\n"
00687 "    (bool) True if dihedral exists and was deleted";
00688 static PyObject* topo_del_dihed(PyObject *self, PyObject *args,
00689                                 PyObject *kwargs) {
00690   const char *kwlist[] = {"i", "j", "k", "l", "molid", NULL};
00691   PyObject *result = Py_False;
00692   int i, j, k, l, tmp, s;
00693   int molid = -1;
00694   Molecule *mol;
00695 
00696   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iiii|i:topology.deldihedral",
00697                                    (char**) kwlist, &i, &j, &k, &l, &molid))
00698     return NULL;
00699 
00700   VMDApp *app;
00701   if (!(app = get_vmdapp()))
00702     return NULL;
00703 
00704   if (molid == -1)
00705     molid = app->molecule_top();
00706 
00707   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00708     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00709     return NULL;
00710   }
00711 
00712   if (i < 0 || j < 0 || k < 0 || l < 0 || k >= mol->nAtoms || 
00713       i >= mol->nAtoms || j >= mol->nAtoms || l >= mol->nAtoms) {
00714     PyErr_Format(PyExc_ValueError, "invalid dihedral atom indices %d-%d-%d-%d",
00715                  i, j, k, l);
00716     return NULL;
00717   }
00718 
00719   //Reorder so i < l as is convention for listing dihedrals
00720   if (i > l) {
00721     tmp = l;
00722     l = i;
00723     i = tmp;
00724     tmp = k;
00725     k = j;
00726     j = tmp;
00727   }
00728 
00729   s = mol->num_dihedrals();
00730   for (tmp = 0; tmp < s; tmp++) {
00731     if (i == mol->dihedrals[4*tmp] && j == mol->dihedrals[4*tmp+1] \
00732      && k == mol->dihedrals[4*tmp+2] && l == mol->dihedrals[4*tmp+3]) {
00733 
00734       mol->dihedrals[4*tmp] = mol->dihedrals[4*s-4];
00735       mol->dihedrals[4*tmp+1] = mol->dihedrals[4*s-3];
00736       mol->dihedrals[4*tmp+2] = mol->dihedrals[4*s-2];
00737       mol->dihedrals[4*tmp+3] = mol->dihedrals[4*s-1];
00738       if (mol->dihedralTypes.num() > tmp) {
00739         if (mol->dihedralTypes.num() == s)
00740           mol->dihedralTypes[tmp] = mol->dihedralTypes[s-1];
00741         else
00742           mol->dihedralTypes[tmp] = -1;
00743       }
00744       mol->dihedrals.pop();
00745       mol->dihedrals.pop();
00746       mol->dihedrals.pop();
00747       mol->dihedrals.pop();
00748       mol->set_dataset_flag(BaseMolecule::ANGLES);
00749 
00750       result = Py_True;
00751       break;
00752     }
00753   }
00754 
00755   Py_INCREF(result);
00756   return result;
00757 }
00758 
00759 
00760 static const char delimproper_doc[] =
00761 "Delete an improper dihedral angle between atoms with the given indices. If\n"
00762 "the improper does not exist, does nothing.\n\n"
00763 "Args:\n"
00764 "    i (int): Index of first atom\n"
00765 "    j (int): Index of second atom\n"
00766 "    k (int): Index of third atom\n"
00767 "    l (int): Index of fourth atom\n"
00768 "    molid (int): Molecule ID to delete from. Defaults to top molecule.\n"
00769 "Returns:\n"
00770 "    (bool) True if improper dihedral exists and was deleted";
00771 static PyObject* topo_del_improper(PyObject *self, PyObject *args,
00772                                    PyObject *kwargs) {
00773   const char *kwlist[] = {"i", "j", "k", "l", "molid", NULL};
00774   PyObject *result = Py_False;
00775   int i, j, k, l, tmp, s;
00776   int molid = -1;
00777   Molecule *mol;
00778 
00779   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iiii|i:topology.delimproper",
00780                                    (char**) kwlist, &i, &j, &k, &l, &molid))
00781     return NULL;
00782 
00783   VMDApp *app;
00784   if (!(app = get_vmdapp()))
00785     return NULL;
00786 
00787   if (molid == -1)
00788     molid = app->molecule_top();
00789 
00790   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00791     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00792     return NULL;
00793   }
00794 
00795   if (i < 0 || j < 0 || k < 0 || l < 0 || k >= mol->nAtoms || 
00796       i >= mol->nAtoms || j >= mol->nAtoms || l >= mol->nAtoms) {
00797     PyErr_Format(PyExc_ValueError, "invalid imporper atom indices %d-%d-%d-%d",
00798                  i, j, k, l);
00799     return NULL;
00800   }
00801 
00802   //Reorder so i < l for convention with dihedral order
00803   if (i > l) {
00804     tmp = l;
00805     l = i;
00806     i = tmp;
00807     tmp = k;
00808     k = j;
00809     j = tmp;
00810   }
00811 
00812   s = mol->num_impropers();
00813   for (tmp = 0; tmp < s; tmp++) {
00814     if (i == mol->impropers[4*tmp  ] && j == mol->impropers[4*tmp+1] && 
00815         k == mol->impropers[4*tmp+2] && l == mol->impropers[4*tmp+3]) {
00816 
00817       mol->impropers[4*tmp  ] = mol->impropers[4*s-4];
00818       mol->impropers[4*tmp+1] = mol->impropers[4*s-3];
00819       mol->impropers[4*tmp+2] = mol->impropers[4*s-2];
00820       mol->impropers[4*tmp+3] = mol->impropers[4*s-1];
00821 
00822       if (mol->improperTypes.num() > tmp) {
00823         if (mol->improperTypes.num() == s)
00824           mol->improperTypes[tmp] = mol->improperTypes[s-1];
00825         else
00826           mol->improperTypes[tmp] = -1;
00827       }
00828       mol->impropers.pop();
00829       mol->impropers.pop();
00830       mol->impropers.pop();
00831       mol->impropers.pop();
00832       mol->set_dataset_flag(BaseMolecule::ANGLES);
00833 
00834       result = Py_True;
00835       break;
00836     }
00837   }
00838 
00839   Py_INCREF(result);
00840   return result;
00841 }
00842 
00843 
00844 static const char del_all_bond_doc[] =
00845 "Delete all bonds in a given molecule\n\n"
00846 "Args:\n"
00847 "    molid (int): Molecule ID to delete bonds in. Defaults to top molecule.\n"
00848 "Returns:\n"
00849 "    (int) Number of bonds deleted";
00850 static PyObject* topo_del_all_bonds(PyObject *self, PyObject *args,
00851                                     PyObject *kwargs) {
00852   const char *kwlist[] = {"molid", NULL};
00853   int molid = -1;
00854   Molecule *mol;
00855 
00856   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:topology.delallbonds",
00857                                    (char**) kwlist, &molid))
00858     return NULL;
00859 
00860   VMDApp *app;
00861   if (!(app = get_vmdapp()))
00862     return NULL;
00863 
00864   if (molid == -1)
00865     molid = app->molecule_top();
00866 
00867   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00868     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00869     return NULL;
00870   }
00871 
00872   int retval = mol->count_bonds();
00873   mol->clear_bonds();
00874 
00875   return as_pyint(retval);
00876 }
00877 
00878 
00879 static const char del_all_angle_doc[] =
00880 "Delete all angles in a given molecule\n\n"
00881 "Args:\n"
00882 "    molid (int): Molecule ID to delete angles in. Defaults to top molecule.\n"
00883 "Returns:\n"
00884 "    (int) Number of angles deleted";
00885 static PyObject* topo_del_all_angles(PyObject *self, PyObject *args,
00886                                      PyObject *kwargs) {
00887   const char *kwlist[] = {"molid", NULL};
00888   int molid = -1;
00889   Molecule *mol;
00890 
00891   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:topology.delallangles",
00892                                    (char**) kwlist, &molid))
00893     return NULL;
00894 
00895   VMDApp *app;
00896   if (!(app = get_vmdapp()))
00897     return NULL;
00898 
00899   if (molid == -1)
00900     molid = app->molecule_top();
00901 
00902   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00903     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00904     return NULL;
00905   }
00906 
00907   int retval = mol->num_angles();
00908   mol->angles.clear();
00909   mol->angleTypes.clear();
00910 
00911   return as_pyint(retval);
00912 }
00913 
00914 
00915 static const char del_all_dihed_doc[] =
00916 "Delete all dihedrals in a given molecule\n\n"
00917 "Args:\n"
00918 "    molid  (int): Molecule ID to delete in. Defaults to top molecule\n"
00919 "Returns:\n"
00920 "    (int) Number of dihedrals deleted";
00921 static PyObject* topo_del_all_dihed(PyObject *self, PyObject *args,
00922                                     PyObject *kwargs) {
00923   const char *kwlist[] = {"molid", NULL};
00924   int molid = -1;
00925   Molecule *mol;
00926 
00927   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:topology.delalldihedrals",
00928                                    (char**) kwlist, &molid))
00929     return NULL;
00930 
00931   VMDApp *app;
00932   if (!(app = get_vmdapp()))
00933     return NULL;
00934 
00935   if (molid == -1)
00936     molid = app->molecule_top();
00937 
00938   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00939     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00940     return NULL;
00941   }
00942 
00943   int retval = mol->num_dihedrals();
00944   mol->dihedrals.clear();
00945   mol->dihedralTypes.clear();
00946 
00947   return as_pyint(retval);
00948 }
00949 
00950 
00951 static const char del_all_improper_doc[] =
00952 "Delete all improper dihedrals in a given molecule\n\n"
00953 "Args:\n"
00954 "    molid  (int): Molecule ID to delete in. Defaults to top molecule\n"
00955 "Returns:\n"
00956 "    (int) Number of impropers deleted";
00957 static PyObject* topo_del_all_impropers(PyObject *self, PyObject *args,
00958                                         PyObject *kwargs) {
00959   const char *kwlist[] = {"molid", NULL};
00960   int molid = -1;
00961   Molecule *mol;
00962 
00963   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:topology.delallimpropers",
00964                                    (char**) kwlist, &molid))
00965     return NULL;
00966 
00967   VMDApp *app;
00968   if (!(app = get_vmdapp()))
00969     return NULL;
00970 
00971   if (molid == -1)
00972     molid = app->molecule_top();
00973 
00974   if (!(mol = app->moleculeList->mol_from_id(molid))) {
00975     PyErr_Format(PyExc_ValueError, "invalid molid '%d'", molid);
00976     return NULL;
00977   }
00978 
00979   int retval = mol->num_impropers();
00980   mol->impropers.clear();
00981   mol->improperTypes.clear();
00982 
00983   return as_pyint(retval);
00984 }
00985 
00986 
00987 static const char btypes_doc[] =
00988 "Get all bond types defined in the molecule. If molecule does not have\n"
00989 "bond types, will return an empty list.\n\n"
00990 "Args:\n"
00991 "    molid (int): Molecule ID to query. Defaults to top molecule\n"
00992 "Returns:\n"
00993 "    (list of str): Bond types in molecule";
00994 static PyObject* topo_bondtypes(PyObject *self, PyObject *args,
00995                                 PyObject *kwargs) {
00996   const char *kwlist[] = {"molid", NULL};
00997   PyObject *returnlist = NULL;
00998   int molid = -1;
00999   Molecule *mol;
01000   int i;
01001 
01002   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:topology.bondtypes",
01003                                    (char**) kwlist, &molid))
01004     return NULL;
01005 
01006   VMDApp *app;
01007   if (!(app = get_vmdapp()))
01008     return NULL;
01009 
01010   if (molid == -1)
01011     molid = app->molecule_top();
01012 
01013   if (!(mol = app->moleculeList->mol_from_id(molid))) {
01014     PyErr_Format(PyExc_ValueError, "Invalid molecule id '%d'", molid);
01015     return NULL;
01016   }
01017 
01018   if (!(returnlist = PyList_New(mol->bondTypeNames.num())))
01019     goto failure;
01020 
01021   for (i = 0; i < mol->bondTypeNames.num(); i++) {
01022     PyList_SET_ITEM(returnlist, i, as_pystring(mol->bondTypeNames.name(i)));
01023     if (PyErr_Occurred())
01024       goto failure;
01025   }
01026 
01027   return returnlist;
01028 
01029 failure:
01030   PyErr_Format(PyExc_RuntimeError, "Problem building bond type list for molid "
01031                "%d", molid);
01032   Py_XDECREF(returnlist);
01033   return NULL;
01034 }
01035 
01036 
01037 static const char atypes_doc[] =
01038 "Get all angle types defined in the molecule. If molecule does not have angle\n"
01039 "types, will return an empty list.\n\n"
01040 "Args:\n"
01041 "    molid (int): Molecule ID to query. Defaults to top molecule\n"
01042 "Returns:\n"
01043 "    (list of str): Angle types in molecule";
01044 static PyObject* topo_angletypes(PyObject *self, PyObject *args,
01045                                 PyObject *kwargs) {
01046   const char *kwlist[] = {"molid", NULL};
01047   PyObject *returnlist = NULL;
01048   int molid = -1;
01049   Molecule *mol;
01050   int i;
01051 
01052   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:topology.angletypes",
01053                                    (char**) kwlist, &molid))
01054     return NULL;
01055 
01056   VMDApp *app;
01057   if (!(app = get_vmdapp()))
01058     return NULL;
01059 
01060   if (molid == -1)
01061     molid = app->molecule_top();
01062 
01063   if (!(mol = app->moleculeList->mol_from_id(molid))) {
01064     PyErr_Format(PyExc_ValueError, "Invalid molecule id '%d'", molid);
01065     return NULL;
01066   }
01067 
01068   if (!(returnlist = PyList_New(mol->angleTypeNames.num())))
01069     goto failure;
01070 
01071   for (i = 0; i < mol->angleTypeNames.num(); i++) {
01072     PyList_SET_ITEM(returnlist, i, as_pystring(mol->angleTypeNames.name(i)));
01073     if (PyErr_Occurred())
01074       goto failure;
01075   }
01076 
01077   return returnlist;
01078 
01079 failure:
01080   PyErr_Format(PyExc_RuntimeError, "Problem building angle type list for molid "
01081                "%d", molid);
01082   Py_XDECREF(returnlist);
01083   return NULL;
01084 }
01085 
01086 
01087 static const char dtypes_doc[] =
01088 "Get all dihedral types defined in the molecule. If the molecule does not\n"
01089 "have dihedral types, will return an empty list.\n\n"
01090 "Args:\n"
01091 "    molid (int): Molecule ID to query. Defaults to top molecule\n"
01092 "Returns:\n"
01093 "    (list of str): Dihedral types in molecule";
01094 static PyObject* topo_dihetypes(PyObject *self, PyObject *args,
01095                                  PyObject *kwargs) {
01096   const char *kwlist[] = {"molid", NULL};
01097   PyObject *returnlist = NULL;
01098   int molid = -1;
01099   Molecule *mol;
01100   int i;
01101 
01102   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:topology.dihedraltypes",
01103                                    (char**) kwlist, &molid))
01104     return NULL;
01105 
01106   VMDApp *app;
01107   if (!(app = get_vmdapp()))
01108     return NULL;
01109 
01110   if (molid == -1)
01111     molid = app->molecule_top();
01112 
01113   if (!(mol = app->moleculeList->mol_from_id(molid))) {
01114     PyErr_Format(PyExc_ValueError, "Invalid molecule id '%d'", molid);
01115     return NULL;
01116   }
01117 
01118   if (!(returnlist = PyList_New(mol->dihedralTypeNames.num())))
01119     goto failure;
01120 
01121   for (i = 0; i < mol->dihedralTypeNames.num(); i++) {
01122     PyList_SET_ITEM(returnlist, i, as_pystring(mol->dihedralTypeNames.name(i)));
01123     if (PyErr_Occurred())
01124       goto failure;
01125   }
01126 
01127   return returnlist;
01128 
01129 failure:
01130   PyErr_Format(PyExc_RuntimeError, "Problem building dihedral type list for "
01131                "molid %d", molid);
01132   Py_XDECREF(returnlist);
01133   return NULL;
01134 }
01135 
01136 
01137 static const char itypes_doc[] =
01138 "Get all improper dihedral types defined in the molecule. If the molecule\n"
01139 "not have improper types, will return an empty list.\n\n"
01140 "Args:\n"
01141 "    molid (int): Molecule ID to query. Defaults to top molecule\n"
01142 "Returns:\n"
01143 "    (list of str): Improper dihedral types in molecule";
01144 static PyObject* topo_imptypes(PyObject *self, PyObject *args, PyObject *kwargs) {
01145   const char *kwlist[] = {"molid", NULL};
01146   PyObject *returnlist = NULL;
01147   int molid = -1;
01148   Molecule *mol;
01149   int i;
01150 
01151   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:topology.impropertypes",
01152                                    (char**) kwlist, &molid))
01153     return NULL;
01154 
01155   VMDApp *app;
01156   if (!(app = get_vmdapp()))
01157     return NULL;
01158 
01159   if (molid == -1)
01160     molid = app->molecule_top();
01161 
01162   if (!(mol = app->moleculeList->mol_from_id(molid))) {
01163     PyErr_Format(PyExc_ValueError, "Invalid molecule id '%d'", molid);
01164     return NULL;
01165   }
01166 
01167   if (!(returnlist = PyList_New(mol->improperTypeNames.num())))
01168     goto failure;
01169 
01170   for (i = 0; i < mol->improperTypeNames.num(); i++) {
01171     PyList_SET_ITEM(returnlist, i, as_pystring(mol->improperTypeNames.name(i)));
01172     if (PyErr_Occurred())
01173       goto failure;
01174   }
01175 
01176   return returnlist;
01177 
01178 failure:
01179   PyErr_Format(PyExc_RuntimeError, "Problem building improper dihedral type "
01180                "list for molid %d", molid);
01181   Py_XDECREF(returnlist);
01182   return NULL;
01183 }
01184 
01185 
01186 static PyMethodDef methods[] = {
01187   {"bonds", (PyCFunction)topo_get_bond, METH_VARARGS | METH_KEYWORDS, bond_doc},
01188   {"angles", (PyCFunction)topo_get_angle, METH_VARARGS | METH_KEYWORDS, angle_doc},
01189   {"dihedrals", (PyCFunction)topo_get_dihed, METH_VARARGS | METH_KEYWORDS, dihed_doc},
01190   {"impropers", (PyCFunction)topo_get_impro, METH_VARARGS | METH_KEYWORDS, impropers_doc},
01191   {"addbond", (PyCFunction)topo_add_bond, METH_VARARGS | METH_KEYWORDS, addbond_doc},
01192   {"addangle", (PyCFunction)topo_add_angle, METH_VARARGS | METH_KEYWORDS, addangle_doc},
01193   {"adddihedral", (PyCFunction)topo_add_dihed, METH_VARARGS | METH_KEYWORDS, adddihed_doc},
01194   {"addimproper", (PyCFunction)topo_add_improp, METH_VARARGS | METH_KEYWORDS, addimproper_doc},
01195   {"delbond", (PyCFunction)topo_del_bond, METH_VARARGS | METH_KEYWORDS, delbond_doc},
01196   {"delangle", (PyCFunction)topo_del_angle, METH_VARARGS | METH_KEYWORDS, delangle_doc},
01197   {"deldihedral", (PyCFunction)topo_del_dihed, METH_VARARGS | METH_KEYWORDS, deldihed_doc},
01198   {"delimproper", (PyCFunction)topo_del_improper, METH_VARARGS | METH_KEYWORDS, delimproper_doc},
01199   {"delallbonds", (PyCFunction)topo_del_all_bonds, METH_VARARGS | METH_KEYWORDS, del_all_bond_doc},
01200   {"delallangles", (PyCFunction)topo_del_all_angles, METH_VARARGS | METH_KEYWORDS, del_all_angle_doc},
01201   {"delalldihedrals", (PyCFunction)topo_del_all_dihed, METH_VARARGS | METH_KEYWORDS, del_all_dihed_doc},
01202   {"delallimpropers", (PyCFunction)topo_del_all_impropers, METH_VARARGS | METH_KEYWORDS, del_all_improper_doc},
01203   {"bondtypes", (PyCFunction)topo_bondtypes, METH_VARARGS | METH_KEYWORDS, btypes_doc},
01204   {"angletypes", (PyCFunction)topo_angletypes, METH_VARARGS | METH_KEYWORDS, atypes_doc},
01205   {"dihedraltypes", (PyCFunction)topo_dihetypes, METH_VARARGS | METH_KEYWORDS, dtypes_doc},
01206   {"impropertypes", (PyCFunction)topo_imptypes, METH_VARARGS | METH_KEYWORDS, itypes_doc},
01207   {NULL, NULL}
01208 };
01209 
01210 
01211 static const char topo_moddoc[] =
01212 "Methods for querying or modifying the topology of a molecule, which consists "
01213 "of all defined bonds, angles, dihedrals, and impropers, for applicable "
01214 "topology file formats.";
01215 
01216 
01217 #if PY_MAJOR_VERSION >= 3
01218 static struct PyModuleDef topologydef = {
01219   PyModuleDef_HEAD_INIT,
01220   "topology",
01221   topo_moddoc,
01222   -1,
01223   methods,
01224 };
01225 #endif
01226 
01227 
01228 PyObject* inittopology(void) {
01229 #if PY_MAJOR_VERSION >= 3
01230   PyObject *m = PyModule_Create(&topologydef);
01231 #else
01232   PyObject *m = Py_InitModule3("topology", methods, topo_moddoc);
01233 #endif
01234 
01235   return m;
01236 }
01237 
01238 

Generated on Fri Nov 8 02:45:27 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002