00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "py_commands.h"
00022 #include <ctype.h>
00023 #include <stdlib.h>
00024
00025 #include "config.h"
00026 #include "utilities.h"
00027 #include "VMDApp.h"
00028 #include "JString.h"
00029 #include "Molecule.h"
00030 #include "MoleculeList.h"
00031
00032
00033 static char mol_num_doc[] =
00034 "num() -> int\n"
00035 "RAeturns the number of loaded molecules.";
00036 static PyObject *mol_num(PyObject *self, PyObject *args) {
00037 if (!PyArg_ParseTuple(args, (char *)":molecule.num"))
00038 return NULL;
00039
00040 return PyInt_FromLong(get_vmdapp()->num_molecules());
00041 }
00042
00043 static char mol_listall_doc[] =
00044 "listall() -> list\n"
00045 "Returns list of all valid molid's.";
00046 static PyObject *mol_listall(PyObject *self, PyObject *args) {
00047 if (!PyArg_ParseTuple(args, (char *)":molecule.listall"))
00048 return NULL;
00049
00050 VMDApp *app = get_vmdapp();
00051 int num = app->num_molecules();
00052 PyObject *newlist = PyList_New(num);
00053 for (int i=0; i<num; i++)
00054 PyList_SET_ITEM(newlist, i, PyInt_FromLong(app->molecule_id(i)));
00055
00056 return newlist;
00057 }
00058
00059 static char mol_exists_doc[] =
00060 "exists(molid) -> boolean\n"
00061 "Return True if molid is valid.";
00062 static PyObject *mol_exists(PyObject *self, PyObject *args) {
00063 int molid;
00064 if (!PyArg_ParseTuple(args, (char *)"i:molecule.exists", &molid))
00065 return NULL;
00066 VMDApp *app = get_vmdapp();
00067 return PyInt_FromLong(app->molecule_valid_id(molid));
00068 }
00069
00070 static char mol_name_doc[] =
00071 "name(molid) -> string\n"
00072 "Returns name of given molecule";
00073 static PyObject *mol_name(PyObject *self, PyObject *args) {
00074 int molid;
00075
00076 if (!PyArg_ParseTuple(args, (char *)"i:molecule.name", &molid))
00077 return NULL;
00078
00079 VMDApp *app = get_vmdapp();
00080 const char *name = app->molecule_name(molid);
00081 if (!name) {
00082 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00083 return NULL;
00084 }
00085 return PyString_FromString((char *)name);
00086 }
00087
00088 static char mol_numatoms_doc[] =
00089 "numatoms (molid) -> int\n"
00090 "Returns number of atoms in given molecule";
00091
00092 static PyObject *mol_numatoms(PyObject *self, PyObject *args) {
00093 int molid;
00094
00095 if (!PyArg_ParseTuple(args, (char *)"i:molecule.numatoms", &molid))
00096 return NULL;
00097
00098 VMDApp *app = get_vmdapp();
00099 if (!app->molecule_valid_id(molid)) {
00100 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00101 return NULL;
00102 }
00103 return PyInt_FromLong(app->molecule_numatoms(molid));
00104 }
00105
00106 static char mol_new_doc[] =
00107 "new(name[,natoms]) -> int\n"
00108 "Creates a new molecule with given name and returns molid. An\n"
00109 "additional integer argument adds that number of 'empty' atoms to the molecule." ;
00110 static PyObject *mol_new(PyObject *self, PyObject *args) {
00111 char *name;
00112 int natoms=0;
00113 if (!PyArg_ParseTuple(args, (char *)"s|i:molecule.new", &name, &natoms))
00114 return NULL;
00115 VMDApp *app = get_vmdapp();
00116 int molid = app->molecule_new(name,natoms);
00117 if (molid < 0) {
00118 PyErr_SetString(PyExc_ValueError, (char *)"Unable to create molecule.");
00119 return NULL;
00120 }
00121 return PyInt_FromLong(molid);
00122 }
00123
00124 static char mol_load_doc[] =
00125 "load(structure, sfname, coor, cfname) -> molid\n"
00126 "Load new molecule with structure file type 'structure', \n"
00127 " structure file name 'sfname', coordinate file type 'coor', and\n"
00128 " coordinate file name 'cfname'. 'coor' and 'cfname' are optional.";
00129
00130 static PyObject *mol_load(PyObject *self, PyObject *args, PyObject *keywds) {
00131
00132 char *structure = NULL, *coor = NULL, *sfname = NULL, *cfname = NULL;
00133
00134 static char *kwlist[] = {
00135 (char *)"structure", (char *)"sfname", (char *)"coor", (char *)"cfname",
00136 NULL
00137 };
00138
00139 if (!PyArg_ParseTupleAndKeywords(args, keywds, (char *)"ss|ss:molecule.load", kwlist,
00140 &structure, &sfname, &coor, &cfname))
00141 return NULL;
00142
00143
00144 if (!structure) {
00145 PyErr_SetString(PyExc_ValueError, (char *)"No structure type specified");
00146 return NULL;
00147 }
00148 if (!sfname) {
00149 PyErr_SetString(PyExc_ValueError, (char *)"No structure file specified");
00150 return NULL;
00151 }
00152
00153
00154
00155 if (coor && !cfname) {
00156 PyErr_SetString(PyExc_ValueError, (char *)"No coordinate file specified");
00157 return NULL;
00158 }
00159 if (cfname && !coor) {
00160 PyErr_SetString(PyExc_ValueError, (char *)"No coordinate type specified");
00161 return NULL;
00162 }
00163
00164
00165 VMDApp *app = get_vmdapp();
00166
00167
00168 if (!strcmp(structure, "graphics")) {
00169 return PyInt_FromLong(app->molecule_new(sfname,0));
00170 }
00171 FileSpec spec;
00172 spec.waitfor=-1;
00173 int molid = app->molecule_load(-1, sfname, structure, &spec);
00174 if (molid < 0) {
00175 PyErr_SetString(PyExc_ValueError, (char *)"Unable to load structure file");
00176 return NULL;
00177 }
00178 if (cfname) {
00179 app->molecule_load(molid, cfname, coor, &spec);
00180 }
00181 return PyInt_FromLong(molid);
00182 }
00183
00184 static char mol_cancel_doc[] =
00185 "cancel(molid) -> None\n"
00186 "Cancel background loading of files for given molid.";
00187 static PyObject *mol_cancel(PyObject *self, PyObject *args) {
00188
00189 int molid;
00190 if (!PyArg_ParseTuple(args, (char *)"i:molecule.cancel", &molid))
00191 return NULL;
00192
00193 VMDApp *app = get_vmdapp();
00194 if (!app->molecule_valid_id(molid)) {
00195 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00196 return NULL;
00197 }
00198 app->molecule_cancel_io(molid);
00199
00200 Py_INCREF(Py_None);
00201 return Py_None;
00202 }
00203
00204 static char mol_delete_doc[] =
00205 "delete(molid) -> None\n"
00206 "Delete molecule with given molid.";
00207 static PyObject *mol_delete(PyObject *self, PyObject *args) {
00208 int molid;
00209 if (!PyArg_ParseTuple(args, (char *)"i:molecule.delete", &molid))
00210 return NULL;
00211
00212 VMDApp *app = get_vmdapp();
00213 if (!app->molecule_valid_id(molid)) {
00214 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00215 return NULL;
00216 }
00217 app->molecule_delete(molid);
00218
00219 Py_INCREF(Py_None);
00220 return Py_None;
00221 }
00222
00223 static char get_top_doc[] =
00224 "get_top(molid) -> molid\n"
00225 "Return molid of top molecule.";
00226 static PyObject *get_top(PyObject *self, PyObject *args) {
00227 if (!PyArg_ParseTuple(args, (char *)":molecule.get_top"))
00228 return NULL;
00229
00230 return PyInt_FromLong(get_vmdapp()->molecule_top());
00231 }
00232
00233 static char set_top_doc[] =
00234 "set_top(molid) -> None\n"
00235 "Make the molecule top.";
00236 static PyObject *set_top(PyObject *self, PyObject *args) {
00237 int molid;
00238 if (!PyArg_ParseTuple(args, (char *)"i:molecule.set_top", &molid))
00239 return NULL;
00240
00241 VMDApp *app = get_vmdapp();
00242 if (!app->molecule_valid_id(molid)) {
00243 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00244 return NULL;
00245 }
00246 app->molecule_make_top(molid);
00247
00248 Py_INCREF(Py_None);
00249 return Py_None;
00250 }
00251
00252
00253 static PyObject *readorwrite(PyObject *self, PyObject *args, PyObject *keywds,
00254 int do_read) {
00255
00256 int molid = -1;
00257 char *filename = NULL, *type = NULL;
00258 int beg=0, end=-1, stride=1, waitfor = do_read ? 1 : -1;
00259 PyObject *volsets = NULL, *selobj = NULL;
00260 int *on = NULL;
00261
00262 static char *kwlist[] = {
00263 (char *)"molid", (char *)"filetype", (char *)"filename", (char *)"beg",
00264 (char *)"end", (char *)"skip", (char *)"waitfor", (char *)"volsets",
00265 (char *)"selection", NULL
00266 };
00267
00268 if (!PyArg_ParseTupleAndKeywords(args, keywds, (char *)"iss|iiiiO!O:read/write", kwlist,
00269 &molid, &type, &filename, &beg, &end, &stride, &waitfor, &PyList_Type,
00270 &volsets, &selobj))
00271 return NULL;
00272
00273 VMDApp *app = get_vmdapp();
00274
00275 int numframes = 0;
00276 if (do_read) {
00277 FileSpec spec;
00278 spec.first = beg;
00279 spec.last = end;
00280 spec.stride = stride;
00281 spec.waitfor = waitfor;
00282 if (volsets) {
00283 spec.nvolsets = PyList_Size(volsets);
00284 spec.setids = new int[spec.nvolsets];
00285 for (int i=0; i<spec.nvolsets; i++)
00286 spec.setids[i] = PyInt_AsLong(PyList_GET_ITEM(volsets, i));
00287 if (PyErr_Occurred()) return NULL;
00288 } else {
00289
00290
00291
00292 spec.nvolsets = 1;
00293 spec.setids = new int[1];
00294 spec.setids[0] = 0;
00295 }
00296 return PyInt_FromLong(app->molecule_load(molid, filename, type, &spec));
00297 }
00298 if (!app->molecule_valid_id(molid)) {
00299 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00300 return NULL;
00301 }
00302 if (selobj && selobj != Py_None) {
00303 AtomSel *sel = atomsel_AsAtomSel( selobj );
00304 if (!sel) return NULL;
00305 if (sel->molid() != molid) {
00306 PyErr_SetString( PyExc_ValueError,
00307 "atomsel must reference same molecule as coordinates" );
00308 return NULL;
00309 }
00310 on = sel->on;
00311 }
00312 FileSpec spec;
00313 spec.first = beg;
00314 spec.last = end;
00315 spec.stride = stride;
00316 spec.waitfor = waitfor;
00317 spec.selection = on;
00318 numframes = app->molecule_savetrajectory(molid, filename, type, &spec);
00319 if (numframes < 0) {
00320 PyErr_SetString(PyExc_ValueError, (char *)"Unable to save file");
00321 return NULL;
00322 }
00323 return PyInt_FromLong(numframes);
00324 }
00325
00326 static char mol_read_doc[] =
00327 "read(molid, filetype, filename, beg=0, end=-1, skip=1, waitfor=1)\n"
00328 "Read data from file 'filename' of type 'filetype' into molecule with\n"
00329 "id 'molid'. molid=-1 creates new molecule. Return number of frames\n"
00330 "read (remaining frames will be loaded in the background.\n"
00331 " First frame = beg; default 0\n"
00332 " Last frame = end; default all frames\n"
00333 " Frame stride = skip; default load all frames\n"
00334 " Frames to load before returning = waitfor; default 1\n";
00335 static PyObject *mol_read(PyObject *self, PyObject *args, PyObject *keywds) {
00336 return readorwrite(self, args, keywds, 1);
00337 }
00338
00339 static char mol_write_doc[] =
00340 "write(molid, filetype, filename, beg=0, end=-1, skip=1, waitfor=-1,\n"
00341 " selection=None)\n"
00342 "Write data into file 'filename' of type 'filetype' from molecule with\n"
00343 "id 'molid'. Return number of frames written (remaining frames will be\n"
00344 "written in the background.\n"
00345 " First frame = beg; default 0\n"
00346 " Last frame = end; default all frames\n"
00347 " Frame stride = skip; default load all frames\n"
00348 " Frames to load before returning = waitfor; default 1\n"
00349 " Specify selection of atoms to write with 'selection' keyword; pass\n"
00350 " tuple of atom indexes as argument.";
00351
00352 static PyObject *mol_write(PyObject *self, PyObject *args, PyObject *keywds) {
00353 return readorwrite(self, args, keywds, 0);
00354 }
00355
00356 static char numframes_doc[] =
00357 "numframes(molid) -> number of frames in molecule with id 'molid'.";
00358 static PyObject *numframes(PyObject *self, PyObject *args) {
00359 int molid;
00360
00361 if (!PyArg_ParseTuple(args, (char *)"i:molecule.numframes", &molid))
00362 return NULL;
00363
00364 VMDApp *app = get_vmdapp();
00365 if (!app->molecule_valid_id(molid)) {
00366 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00367 return NULL;
00368 }
00369 return PyInt_FromLong(app->molecule_numframes(molid));
00370 }
00371
00372 static char get_frame_doc[] =
00373 "get_frame(molid) -> current frame of molecule with id 'molid'.";
00374 static PyObject *get_frame(PyObject *self, PyObject *args) {
00375 int molid;
00376
00377 if (!PyArg_ParseTuple(args, (char *)"i:molecule.get_frame", &molid))
00378 return NULL;
00379
00380 VMDApp *app = get_vmdapp();
00381 if (!app->molecule_valid_id(molid)) {
00382 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00383 return NULL;
00384 }
00385 return PyInt_FromLong(app->molecule_frame(molid));
00386 }
00387
00388 static char set_frame_doc[] =
00389 "set_frame(molid, frame)\n"
00390 "Change frame of molecule with id 'molid' to 'frame'.";
00391
00392 static PyObject *set_frame(PyObject *self, PyObject *args) {
00393 int molid, frame;
00394
00395 if (!PyArg_ParseTuple(args, (char *)"ii:molecule.set_frame", &molid, &frame))
00396 return NULL;
00397
00398 VMDApp *app = get_vmdapp();
00399 Molecule *mol = app->moleculeList->mol_from_id(molid);
00400 if (!mol) {
00401 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00402 return NULL;
00403 }
00404 mol->override_current_frame(frame);
00405 mol->change_ts();
00406 Py_INCREF(Py_None);
00407 return Py_None;
00408 }
00409
00410 static char delframe_doc[] =
00411 "delframe(molid, beg=0, end=-1, skip=0)\n"
00412 "Delete frames in the range [beg, end] inclusive, keeping every\n"
00413 " 'skip' frame between beg and end.";
00414 static PyObject *delframe(PyObject *self, PyObject *args, PyObject *keywds) {
00415
00416 int molid = 0, beg=0, end=-1, skip=0;
00417
00418 static char *kwlist[] = {
00419 (char *)"molid", (char *)"beg", (char *)"end", (char *)"skip", NULL
00420 };
00421
00422 if (!PyArg_ParseTupleAndKeywords(args, keywds, (char *)"i|iii:molecule.delframe", kwlist,
00423 &molid, &beg, &end, &skip))
00424 return NULL;
00425
00426 VMDApp *app = get_vmdapp();
00427 if (!app->molecule_valid_id(molid)) {
00428 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molid");
00429 return NULL;
00430 }
00431
00432 if (!app->molecule_deleteframes(molid, beg, end, skip)) {
00433 PyErr_SetString(PyExc_ValueError, (char *)"Unable to delete frames");
00434 return NULL;
00435 }
00436
00437 Py_INCREF(Py_None);
00438 return Py_None;
00439 }
00440
00441 static char dupframe_doc[] =
00442 "dupframe(molid, frame) -> Duplicate given frame.\n"
00443 "If frame is -1, duplicate the current frame; this also creates\n"
00444 "a new frame with coordinates all zero if there are no frames in\n"
00445 "the molecule.";
00446 static PyObject *dupframe(PyObject *self, PyObject *args) {
00447
00448 int molid, frame;
00449 if (!PyArg_ParseTuple(args, (char *)"ii:molecule.dupframe", &molid, &frame))
00450 return NULL;
00451
00452 VMDApp *app = get_vmdapp();
00453 if (!app->molecule_valid_id(molid)) {
00454 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molid");
00455 return NULL;
00456 }
00457
00458 if (!app->molecule_dupframe(molid, frame)) {
00459 PyErr_SetString(PyExc_ValueError, (char *)"Unable to duplicate frame");
00460 return NULL;
00461 }
00462 Py_INCREF(Py_None);
00463 return Py_None;
00464 }
00465
00466 static char mol_ssrecalc_doc[] =
00467 "ssrecalc(molid) -> recalculate secondary structure for molecule.\n"
00468 "raises RuntimeError if structure could not be calculated, usually\n"
00469 "due to the Stride program not being available.";
00470 static PyObject *mol_ssrecalc(PyObject *self, PyObject *args) {
00471 int molid;
00472 if (!PyArg_ParseTuple(args, (char *)"i:molecule.ssrecalc", &molid))
00473 return NULL;
00474
00475 VMDApp *app = get_vmdapp();
00476 if (!app->molecule_valid_id(molid)) {
00477 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00478 return NULL;
00479 }
00480 int rc;
00481 Py_BEGIN_ALLOW_THREADS
00482 rc = app->molecule_ssrecalc(molid);
00483 Py_END_ALLOW_THREADS
00484 if (!rc) {
00485 PyErr_SetString(PyExc_RuntimeError,
00486 "Secondary structure could not be calculated");
00487 return NULL;
00488 }
00489 Py_INCREF(Py_None);
00490 return Py_None;
00491 }
00492
00493 static char mol_rename_doc[] =
00494 "rename(molid, newname) -> rename molecule to 'newname'.";
00495 static PyObject *mol_rename(PyObject *self, PyObject *args) {
00496 int molid;
00497 char *newname;
00498 if (!PyArg_ParseTuple(args, (char *)"is:molecule.rename", &molid, &newname))
00499 return NULL;
00500
00501 VMDApp *app = get_vmdapp();
00502 if (!app->molecule_valid_id(molid)) {
00503 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00504 return NULL;
00505 }
00506 if (!app->molecule_rename(molid, newname)) {
00507 PyErr_SetString(PyExc_ValueError, (char *)"Unable to rename molecule.");
00508 return NULL;
00509 }
00510 Py_INCREF(Py_None);
00511 return Py_None;
00512 }
00513
00514 static char add_volumetric_doc[] =
00515 "add_volumetric(molid, name, origin, xaxis, yaxis, zaxis,\n"
00516 " xsize, ysize, zsize, data)\n"
00517 " Add a new volumetric data set to a molecule. origin, xaxis, yaxis,\n"
00518 " and zaxis are 3-vectors represented as lists. xsize, ysize, zsize\n"
00519 " give the size of the volumetric grid data. data must be a list of\n"
00520 " floats of size xsize * ysize * zsize. origin represents the point\n"
00521 " at the lower left rear corner of the grid.";
00522 static PyObject *mol_add_volumetric(PyObject *self, PyObject *args, PyObject *keywds) {
00523
00524 int molid = -1;
00525 int xsize = -1, ysize = -1, zsize = -1;
00526 int size;
00527 char *name;
00528 PyObject *data = NULL, *origin = NULL, *xaxis = NULL, *yaxis = NULL,
00529 *zaxis = NULL;
00530 float forigin[3], fxaxis[3], fyaxis[3], fzaxis[3];
00531
00532 static char *kwlist[] = {
00533 (char *)"molid", (char *)"name", (char *)"origin", (char *)"xaxis",
00534 (char *)"yaxis", (char *)"zaxis", (char *)"xsize", (char *)"ysize",
00535 (char *)"zsize", (char *)"data", NULL
00536 };
00537
00538 if (!PyArg_ParseTupleAndKeywords(args, keywds,
00539 (char *)"isOOOOiiiO:molecule.add_volumetric", kwlist,
00540 &molid, &name, &origin, &xaxis, &yaxis, &zaxis, &xsize,
00541 &ysize, &zsize, &data))
00542 return NULL;
00543
00544 VMDApp *app = get_vmdapp();
00545 if (!app->molecule_valid_id(molid)) {
00546 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00547 return NULL;
00548 }
00549 if (xsize < 1 || ysize < 1 || zsize < 1) {
00550 PyErr_SetString(PyExc_ValueError, (char *)"Invalid size parameters");
00551 return NULL;
00552 }
00553 size = xsize * ysize * zsize;
00554 if (!PyList_Check(data)) {
00555 PyErr_SetString(PyExc_ValueError, (char *)"data must be a list");
00556 return NULL;
00557 }
00558 if (PyList_Size(data) != size) {
00559 PyErr_SetString(PyExc_ValueError, (char *)"size of list does not match specified sizes");
00560 return NULL;
00561 }
00562
00563 if (origin) {
00564 if (!py_array_from_obj(origin, forigin)) return NULL;
00565 } else {
00566 forigin[0] = forigin[1] = forigin[2] = 0;
00567 }
00568 if (xaxis) {
00569 if (!py_array_from_obj(xaxis, fxaxis)) return NULL;
00570 } else {
00571 fxaxis[0] = 1.0; fxaxis[1] = fxaxis[2] = 0;
00572 }
00573 if (yaxis) {
00574 if (!py_array_from_obj(yaxis, fyaxis)) return NULL;
00575 } else {
00576 fyaxis[1] = 1.0; fyaxis[0] = fyaxis[2] = 0;
00577 }
00578 if (zaxis) {
00579 if (!py_array_from_obj(zaxis, fzaxis)) return NULL;
00580 } else {
00581 fzaxis[2] = 1.0; fzaxis[0] = fzaxis[1] = 0;
00582 }
00583
00584
00585 float *fdata = new float[size];
00586 for (int i=0; i<size; i++) {
00587 PyObject *elem = PyList_GET_ITEM(data, i);
00588 float tmp = PyFloat_AsDouble(elem);
00589 if (PyErr_Occurred()) {
00590 delete [] fdata;
00591 return NULL;
00592 }
00593 fdata[i] = tmp;
00594 }
00595 if (!app->molecule_add_volumetric(molid, name, forigin, fxaxis, fyaxis,
00596 fzaxis, xsize, ysize, zsize, fdata)) {
00597 PyErr_SetString(PyExc_ValueError, (char *)"Unable to add volumetric data");
00598 delete [] fdata;
00599 return NULL;
00600 }
00601 Py_INCREF(Py_None);
00602 return Py_None;
00603 }
00604
00605 static char filenames_doc[] = "get_filenames(molid): return list of files loaded in the molecule";
00606 static char filetypes_doc[] = "get_filetypes(molid): returns list of corresponding file types.";
00607 static char databases_doc[] = "get_databases(molid): returns list of databases of origin ";
00608 static char accessions_doc[] = "get_accessions(molid): returns list of database accession codes";
00609 static char remarks_doc[] = "get_remarks(molid): returns list of per-file remarks/comments";
00610 static PyObject *get_filenames(PyObject *self, PyObject *args) {
00611 int molid;
00612 if (!PyArg_ParseTuple(args, (char *)"i:molecule.get_filenames", &molid))
00613 return NULL;
00614
00615 VMDApp *app = get_vmdapp();
00616 Molecule *mol = app->moleculeList->mol_from_id(molid);
00617 if (!mol) {
00618 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00619 return NULL;
00620 }
00621 int num = mol->num_files();
00622 PyObject *result = PyList_New(num);
00623 for (int i=0; i<mol->num_files(); i++) {
00624 PyList_SET_ITEM(result, i, PyString_FromString(mol->get_file(i)));
00625 }
00626 return result;
00627 }
00628 static PyObject *get_filetypes(PyObject *self, PyObject *args) {
00629 int molid;
00630 if (!PyArg_ParseTuple(args, (char *)"i:molecule.get_filetypes", &molid))
00631 return NULL;
00632
00633 VMDApp *app = get_vmdapp();
00634 Molecule *mol = app->moleculeList->mol_from_id(molid);
00635 if (!mol) {
00636 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00637 return NULL;
00638 }
00639 int num = mol->num_files();
00640 PyObject *result = PyList_New(num);
00641 for (int i=0; i<mol->num_files(); i++) {
00642 PyList_SET_ITEM(result, i, PyString_FromString(mol->get_type(i)));
00643 }
00644 return result;
00645 }
00646 static PyObject *get_databases(PyObject *self, PyObject *args) {
00647 int molid;
00648 if (!PyArg_ParseTuple(args, (char *)"i:molecule.get_databases", &molid))
00649 return NULL;
00650
00651 VMDApp *app = get_vmdapp();
00652 Molecule *mol = app->moleculeList->mol_from_id(molid);
00653 if (!mol) {
00654 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00655 return NULL;
00656 }
00657 int num = mol->num_files();
00658 PyObject *result = PyList_New(num);
00659 for (int i=0; i<mol->num_files(); i++) {
00660 PyList_SET_ITEM(result, i, PyString_FromString(mol->get_database(i)));
00661 }
00662 return result;
00663 }
00664 static PyObject *get_accessions(PyObject *self, PyObject *args) {
00665 int molid;
00666 if (!PyArg_ParseTuple(args, (char *)"i:molecule.get_accessions", &molid))
00667 return NULL;
00668
00669 VMDApp *app = get_vmdapp();
00670 Molecule *mol = app->moleculeList->mol_from_id(molid);
00671 if (!mol) {
00672 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00673 return NULL;
00674 }
00675 int num = mol->num_files();
00676 PyObject *result = PyList_New(num);
00677 for (int i=0; i<mol->num_files(); i++) {
00678 PyList_SET_ITEM(result, i, PyString_FromString(mol->get_accession(i)));
00679 }
00680 return result;
00681 }
00682 static PyObject *get_remarks(PyObject *self, PyObject *args) {
00683 int molid;
00684 if (!PyArg_ParseTuple(args, (char *)"i:molecule.get_remarks", &molid))
00685 return NULL;
00686
00687 VMDApp *app = get_vmdapp();
00688 Molecule *mol = app->moleculeList->mol_from_id(molid);
00689 if (!mol) {
00690 PyErr_SetString(PyExc_ValueError, (char *)"Invalid molecule id");
00691 return NULL;
00692 }
00693 int num = mol->num_files();
00694 PyObject *result = PyList_New(num);
00695 for (int i=0; i<mol->num_files(); i++) {
00696 PyList_SET_ITEM(result, i, PyString_FromString(mol->get_remarks(i)));
00697 }
00698 return result;
00699 }
00700
00701
00702 static char get_periodic_doc[] =
00703 "get_periodic(molid=-1, frame=-1)\n"
00704 "return dict with keys 'a', 'b', 'c', 'alpha', 'beta', and 'gamma'\n"
00705 "representing the periodic cell layout for a particular frame.\n"
00706 "a, b, and c are the lengths of the unit cell along the first, second\n"
00707 "and third unit cell vectors, respectively. alpha, beta, and gamma\n"
00708 "give the angle between sides B and C, A and C, and A and B,\n"
00709 "respectively.";
00710 static PyObject *get_periodic(PyObject *self, PyObject *args, PyObject *kwds) {
00711 int molid=-1;
00712 int frame=-1;
00713 static char *kwlist[] = { (char *)"molid", (char *)"frame", NULL };
00714 if (!PyArg_ParseTupleAndKeywords(args, kwds, (char *)"|ii:molecule.get_periodic", kwlist, &molid, &frame))
00715 return NULL;
00716
00717 Timestep *ts = parse_timestep(get_vmdapp(), molid, frame);
00718 if (!ts) return NULL;
00719 PyObject *dict = PyDict_New();
00720 PyDict_SetItemString(dict, (char *)"a", PyFloat_FromDouble(ts->a_length));
00721 PyDict_SetItemString(dict, (char *)"b", PyFloat_FromDouble(ts->b_length));
00722 PyDict_SetItemString(dict, (char *)"c", PyFloat_FromDouble(ts->c_length));
00723 PyDict_SetItemString(dict, (char *)"alpha", PyFloat_FromDouble(ts->alpha));
00724 PyDict_SetItemString(dict, (char *)"beta", PyFloat_FromDouble(ts->beta));
00725 PyDict_SetItemString(dict, (char *)"gamma", PyFloat_FromDouble(ts->gamma));
00726 return dict;
00727 }
00728
00729 static char set_periodic_doc[] =
00730 "set_periodic(molid=-1, frame=-1, a, b, c, alpha, beta, gamma)\n"
00731 "Set the periodic cell layout for a particular frame.\n"
00732 "All keywords except molid are optional. See get_periodic for\n"
00733 "descriptions of the keywords.";
00734 static PyObject *set_periodic(PyObject *self, PyObject *args, PyObject *kwds) {
00735 int molid=-1;
00736 int frame=-1;
00737 float a=-1, b=-1, c=-1, alpha=-1, beta=-1, gamma=-1;
00738 static char *kwlist[] = { (char *)"molid", (char *)"frame", (char *)"a",
00739 (char *)"b", (char *)"c", (char *)"alpha", (char *)"beta", (char *)"gamma",
00740 NULL
00741 };
00742 if (!PyArg_ParseTupleAndKeywords(args, kwds,
00743 (char *)"|iiffffff:molecule.set_periodic", kwlist,
00744 &molid, &frame, &a, &b, &c, &alpha, &beta, &gamma))
00745 return NULL;
00746 Timestep *ts = parse_timestep(get_vmdapp(), molid, frame);
00747 if (!ts) return NULL;
00748 if (a >= 0) ts->a_length = a;
00749 if (b >= 0) ts->b_length = b;
00750 if (c >= 0) ts->c_length = c;
00751 if (alpha > 0) ts->alpha = alpha;
00752 if (beta > 0) ts->beta = beta;
00753 if (gamma > 0) ts->gamma = gamma;
00754
00755 Py_INCREF(Py_None);
00756 return Py_None;
00757 }
00758
00759 static char get_visible_doc[] =
00760 "get_visible(molid=-1) -> boolean\n"
00761 " Get visibility state for selected molecule, default top molecule\n";
00762 static char set_visible_doc[] =
00763 "set_visible(molid=-1, state)\n"
00764 " Turn selected molecule on or off, default top molecule\n";
00765
00766 static PyObject *get_visible(PyObject *self, PyObject *args, PyObject *kwds) {
00767 int molid = -1;
00768 static char *kwlist[] = { "molid", NULL };
00769 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &molid))
00770 return NULL;
00771 VMDApp *app = get_vmdapp();
00772 if (!app) return NULL;
00773 if (molid<0) molid = app->molecule_top();
00774 if (!app->molecule_valid_id(molid)) {
00775 PyErr_SetString(PyExc_ValueError, "Invalid molid");
00776 return NULL;
00777 }
00778 return PyBool_FromLong( app->molecule_is_displayed( molid ) );
00779 }
00780 static PyObject *set_visible(PyObject *self, PyObject *args, PyObject *kwds) {
00781 int molid = -1;
00782 PyObject *obj=NULL;
00783
00784 static char *kwlist[] = { "molid", "state", NULL };
00785 if (!PyArg_ParseTupleAndKeywords(args, kwds, "iO", kwlist, &molid, &obj))
00786 return NULL;
00787 VMDApp *app = get_vmdapp();
00788 if (!app) return NULL;
00789 if (molid<0) molid = app->molecule_top();
00790 if (!app->molecule_valid_id(molid)) {
00791 PyErr_SetString(PyExc_ValueError, "Invalid molid");
00792 return NULL;
00793 }
00794 app->molecule_display( molid, PyObject_IsTrue(obj));
00795 Py_INCREF(Py_None);
00796 return Py_None;
00797 }
00798
00799 static PyObject *get_physical_time(PyObject *self, PyObject *args, PyObject *kwds) {
00800 int molid = -1;
00801 int frame = -1;
00802 static char *kwlist[] = { "molid", "frame", NULL };
00803 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist, &molid, &frame))
00804 return NULL;
00805 Timestep *ts = parse_timestep(get_vmdapp(), molid, frame);
00806 if (!ts) return NULL;
00807 return PyFloat_FromDouble(ts->physical_time);
00808 }
00809
00810 static PyObject *set_physical_time(PyObject *self, PyObject *args, PyObject *kwds) {
00811 int molid = -1;
00812 int frame = -1;
00813 double value;
00814 static char *kwlist[] = { "value", "molid", "frame", NULL };
00815 if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|ii", kwlist, &value, &molid, &frame))
00816 return NULL;
00817 Timestep *ts = parse_timestep(get_vmdapp(), molid, frame);
00818 if (!ts) return NULL;
00819 ts->physical_time = value;
00820
00821 Py_INCREF(Py_None);
00822 return Py_None;
00823 }
00824
00825 static PyMethodDef MolMethods[] = {
00826 {(char *)"num", (vmdPyMethod)mol_num, METH_VARARGS, mol_num_doc },
00827 {(char *)"listall", (vmdPyMethod)mol_listall, METH_VARARGS,mol_listall_doc},
00828 {(char *)"new", (vmdPyMethod)mol_new, METH_VARARGS, mol_new_doc},
00829 {(char *)"load", (PyCFunction)mol_load, METH_VARARGS | METH_KEYWORDS, mol_load_doc},
00830 {(char *)"cancel", (vmdPyMethod)mol_cancel, METH_VARARGS, mol_cancel_doc},
00831 {(char *)"delete", (vmdPyMethod)mol_delete, METH_VARARGS, mol_delete_doc},
00832 {(char *)"read", (PyCFunction)mol_read, METH_VARARGS | METH_KEYWORDS, mol_read_doc},
00833 {(char *)"write", (PyCFunction)mol_write, METH_VARARGS | METH_KEYWORDS, mol_write_doc},
00834 {(char *)"delframe", (PyCFunction)delframe, METH_VARARGS | METH_KEYWORDS, delframe_doc},
00835 {(char *)"dupframe", (vmdPyMethod)dupframe, METH_VARARGS, dupframe_doc},
00836 {(char *)"numframes", (vmdPyMethod)numframes, METH_VARARGS, numframes_doc},
00837 {(char *)"get_frame", (vmdPyMethod)get_frame, METH_VARARGS, get_frame_doc},
00838 {(char *)"set_frame", (vmdPyMethod)set_frame, METH_VARARGS, set_frame_doc},
00839 {(char *)"numatoms", (vmdPyMethod)mol_numatoms, METH_VARARGS, mol_numatoms_doc},
00840 {(char *)"exists", (vmdPyMethod)mol_exists, METH_VARARGS, mol_exists_doc},
00841 {(char *)"name", (vmdPyMethod)mol_name, METH_VARARGS, mol_name_doc},
00842 {(char *)"ssrecalc", (vmdPyMethod)mol_ssrecalc, METH_VARARGS, mol_ssrecalc_doc},
00843 {(char *)"rename", (vmdPyMethod)mol_rename, METH_VARARGS, mol_rename_doc},
00844 {(char *)"get_top", (vmdPyMethod)get_top, METH_VARARGS, get_top_doc},
00845 {(char *)"set_top", (vmdPyMethod)set_top, METH_VARARGS, set_top_doc},
00846 {(char *)"add_volumetric", (PyCFunction)mol_add_volumetric,
00847 METH_VARARGS | METH_KEYWORDS, add_volumetric_doc},
00848 {(char *)"get_filenames", (vmdPyMethod)get_filenames, METH_VARARGS, filenames_doc},
00849 {(char *)"get_filetypes", (vmdPyMethod)get_filetypes, METH_VARARGS, filetypes_doc},
00850 {(char *)"get_databases", (vmdPyMethod)get_databases, METH_VARARGS, databases_doc},
00851 {(char *)"get_accessions", (vmdPyMethod)get_accessions, METH_VARARGS, accessions_doc},
00852 {(char *)"get_remarks", (vmdPyMethod)get_remarks, METH_VARARGS, remarks_doc},
00853 {(char *)"get_periodic", (PyCFunction)get_periodic, METH_VARARGS | METH_KEYWORDS, get_periodic_doc},
00854 {(char *)"set_periodic", (PyCFunction)set_periodic, METH_VARARGS | METH_KEYWORDS, set_periodic_doc},
00855 {(char *)"get_visible", (PyCFunction)get_visible, METH_VARARGS | METH_KEYWORDS, get_visible_doc},
00856 {(char *)"set_visible", (PyCFunction)set_visible, METH_VARARGS | METH_KEYWORDS, set_visible_doc},
00857 {(char *)"get_physical_time", (PyCFunction)get_physical_time, METH_VARARGS | METH_KEYWORDS },
00858 {(char *)"set_physical_time", (PyCFunction)set_physical_time, METH_VARARGS | METH_KEYWORDS },
00859 {NULL, NULL}
00860 };
00861
00862 void initmolecule() {
00863 (void) Py_InitModule((char *)"molecule", MolMethods);
00864 }
00865