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
00034 void handle_legacy_keywords(PyObject *kwargs)
00035 {
00036 PyObject *value;
00037 int warn = 0;
00038
00039
00040 if (!kwargs)
00041 return;
00042
00043
00044 if ((value = PyDict_GetItemString(kwargs, "beg"))) {
00045 PyDict_SetItemString(kwargs, "first", value);
00046 PyDict_DelItemString(kwargs, "beg");
00047 warn = 1;
00048 }
00049
00050
00051 if ((value = PyDict_GetItemString(kwargs, "end"))) {
00052 PyDict_SetItemString(kwargs, "last", value);
00053 PyDict_DelItemString(kwargs, "end");
00054 warn = 1;
00055 }
00056
00057
00058 if ((value = PyDict_GetItemString(kwargs, "skip"))) {
00059 PyDict_SetItemString(kwargs, "stride", value);
00060 PyDict_DelItemString(kwargs, "skip");
00061 warn = 1;
00062 }
00063
00064 if (warn) {
00065 PyErr_Warn(PyExc_DeprecationWarning, "beg, end, skip keywords are now "
00066 "first, last, stride");
00067 }
00068 }
00069
00070 static const char mol_num_doc[] =
00071 "Get the number of loaded molecules\n\n"
00072 "Returns:\n"
00073 " (int): Number of molecules";
00074 static PyObject* py_mol_num(PyObject *self, PyObject *args)
00075 {
00076 VMDApp *app;
00077 if (!(app = get_vmdapp()))
00078 return NULL;
00079
00080 return as_pyint(app->num_molecules());
00081 }
00082
00083 static const char mol_listall_doc[] =
00084 "List all valid molecule IDs\n\n"
00085 "Returns:\n"
00086 " (list of int): Molids";
00087 static PyObject* py_mol_listall(PyObject *self, PyObject *args) {
00088 PyObject *newlist = NULL;
00089 int i;
00090
00091 VMDApp *app;
00092 if (!(app = get_vmdapp()))
00093 return NULL;
00094
00095 int num = app->num_molecules();
00096 if (!(newlist = PyList_New(num)))
00097 goto failure;
00098
00099 for (i = 0; i < num; i++) {
00100 PyList_SET_ITEM(newlist, i, as_pyint(app->molecule_id(i)));
00101 if (PyErr_Occurred())
00102 goto failure;
00103 }
00104 return newlist;
00105
00106 failure:
00107 Py_XDECREF(newlist);
00108 PyErr_SetString(PyExc_ValueError, "Problem listing molids");
00109 return NULL;
00110 }
00111
00112 static const char mol_exists_doc[] =
00113 "Check if a molecule ID is valid\n\n"
00114 "Args:\n"
00115 " molid (int): Molecule ID to query\n"
00116 "Returns:\n"
00117 " (bool) True if molid is valid";
00118 static PyObject* py_mol_exists(PyObject *self, PyObject *args, PyObject *kwargs)
00119 {
00120 const char *kwlist[] = {"molid", NULL};
00121 int molid;
00122
00123 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.exists",
00124 (char**) kwlist, &molid))
00125 return NULL;
00126
00127 VMDApp *app;
00128 if (!(app = get_vmdapp()))
00129 return NULL;
00130
00131 return as_pyint(app->molecule_valid_id(molid));
00132 }
00133
00134 static const char mol_name_doc[] =
00135 "Get name of a given molecule\n\n"
00136 "Args:\n"
00137 " molid (int): Molecule ID to query\n"
00138 "Returns:\n"
00139 " (str): Molecule name";
00140 static PyObject* py_mol_name(PyObject *self, PyObject *args, PyObject *kwargs)
00141 {
00142 const char *kwlist[] = {"molid", NULL};
00143 int molid;
00144
00145 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.name",
00146 (char**) kwlist, &molid))
00147 return NULL;
00148
00149 VMDApp *app;
00150 if (!(app = get_vmdapp()))
00151 return NULL;
00152
00153 if (!valid_molid(molid, app))
00154 return NULL;
00155
00156 return as_pystring(app->molecule_name(molid));
00157 }
00158
00159 static const char mol_numatoms_doc[] =
00160 "Get number of atoms in a given molecule\n\n"
00161 "Args:\n"
00162 " molid (int): Molecule ID to query\n"
00163 "Returns:\n"
00164 " (int): Number of atoms present in molecule";
00165 static PyObject* py_mol_numatoms(PyObject *self, PyObject *args,
00166 PyObject *kwargs)
00167 {
00168 const char *kwlist[] = {"molid", NULL};
00169 int molid;
00170
00171 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.numatoms",
00172 (char**) kwlist, &molid))
00173 return NULL;
00174
00175 VMDApp *app;
00176 if (!(app = get_vmdapp()))
00177 return NULL;
00178
00179 if (!valid_molid(molid, app))
00180 return NULL;
00181
00182 return as_pyint(app->molecule_numatoms(molid));
00183 }
00184
00185 static const char mol_new_doc[] =
00186 "Create a new molecule, with optional number of 'empty' atoms\n\n"
00187 "Args:\n"
00188 " name (str): Name of new molecule\n"
00189 " natoms (int): Number of empty atoms in new molecule, optional.\n"
00190 "Returns:\n"
00191 " (int): Molecule ID of created molecule";
00192 static PyObject* py_mol_new(PyObject *self, PyObject *args, PyObject *kwargs)
00193 {
00194 const char *kwlist[] = {"name", "natoms", NULL};
00195 int natoms = 0;
00196 char *name;
00197
00198 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:molecule.new",
00199 (char**) kwlist, &name, &natoms))
00200 return NULL;
00201
00202 VMDApp *app;
00203 if (!(app = get_vmdapp()))
00204 return NULL;
00205
00206 if (natoms < 0) {
00207 PyErr_SetString(PyExc_ValueError, "natoms must be >= 0");
00208 return NULL;
00209 }
00210
00211 int molid = app->molecule_new(name,natoms);
00212
00213 if (molid < 0) {
00214 PyErr_Format(PyExc_ValueError, "Unable to create molecule name '%s'", name);
00215 return NULL;
00216 }
00217
00218 return as_pyint(molid);
00219 }
00220
00221 static const char mol_fromsel_doc[] =
00222 "Create a new molecule from multiple atomselections\n\n"
00223 "Args:\n"
00224 " sellist (list): List of atomselections to be fused into a single molecule\n"
00225 " name (str): Name of new molecule (optional)\n"
00226 "Returns:\n"
00227 " (int): Molecule ID of created molecule";
00228 static PyObject* py_mol_fromsel(PyObject *self, PyObject *args, PyObject *kwargs)
00229 {
00230 const char *kwlist[] = {"", "name", NULL};
00231 PyObject *listObj;
00232 char *name = NULL;
00233
00234 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|s:molecule.fromsel",
00235 (char**) kwlist, &PyList_Type, &listObj, &name))
00236 return NULL;
00237
00238 VMDApp *app;
00239 if (!(app = get_vmdapp()))
00240 return NULL;
00241
00242 AtomSel **asels = (AtomSel **) calloc(1, PyList_Size(listObj) * sizeof(AtomSel *));
00243 int s;
00244 int numsels = PyList_Size(listObj);
00245 for (s=0; s<numsels; s++) {
00246 asels[s] = atomsel_AsAtomSel(PyList_GetItem(listObj, s));
00247 if (!asels[s]) {
00248 PyErr_SetString(PyExc_ValueError, "mol fromsels: invalid atom selection list element");
00249 return NULL;
00250 }
00251 }
00252 int molid = app->molecule_from_selection_list(name, 0, numsels, asels);
00253 free(asels);
00254
00255 if (molid < 0) {
00256 PyErr_Format(PyExc_ValueError, "Unable to create new molecule");
00257 return NULL;
00258 }
00259
00260 return as_pyint(molid);
00261 }
00262
00263 static const char mol_load_doc[] =
00264 "Load a molecule from a file. Can optionally read in coordinate files as\n"
00265 "well. Coordinate data does not have to be present in structure file\n"
00266 "Args:\n"
00267 " struct_type (str): File type for structure data, or 'graphics' for\n"
00268 " a blank molecule to add graphics to.\n"
00269 " struct_file (str): Filename for structure data\n"
00270 " coord_type (str): File type for coordinate data. Optional.\n"
00271 " coord_file (str): Filename for coordinate data. Optional.\n"
00272 "Returns:\n"
00273 " (int): Molecule ID of loaded molecule";
00274 static PyObject* py_mol_load(PyObject *self, PyObject *args, PyObject *kwargs)
00275 {
00276 const char *kwlist[] = {"struct_type", "struct_file", "coord_type",
00277 "coord_file", NULL};
00278 char *coor = NULL, *cfname = NULL;
00279 char *structure, *sfname;
00280 FileSpec spec;
00281 int molid;
00282
00283 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss|zz:molecule.load",
00284 (char**) kwlist, &structure, &sfname,
00285 &coor, &cfname))
00286 return NULL;
00287
00288
00289
00290 if (coor && !cfname) {
00291 PyErr_SetString(PyExc_ValueError, "No coordinate file specified");
00292 return NULL;
00293 }
00294 if (cfname && !coor) {
00295 PyErr_SetString(PyExc_ValueError, "No coordinate type specified");
00296 return NULL;
00297 }
00298
00299 VMDApp *app;
00300 if (!(app = get_vmdapp()))
00301 return NULL;
00302
00303
00304 if (!strcmp(structure, "graphics"))
00305 return as_pyint(app->molecule_new(sfname, 0));
00306
00307
00308 spec.waitfor = FileSpec::WAIT_ALL;
00309 molid = app->molecule_load(-1, sfname, structure, &spec);
00310 if (molid < 0) {
00311 PyErr_Format(PyExc_RuntimeError, "Unable to load structure file '%s' "
00312 "format '%s'", sfname, structure);
00313 return NULL;
00314 }
00315
00316
00317 if (cfname && (app->molecule_load(molid, cfname, coor, &spec) < 0)) {
00318 PyErr_Format(PyExc_RuntimeError, "Unable to load coordinate file '%s' "
00319 "format '%s'", cfname, coor);
00320 }
00321
00322 return as_pyint(molid);
00323 }
00324
00325 static const char mol_cancel_doc[] =
00326 "Cancel background loading of files for given molid\n\n"
00327 "Args:\n"
00328 " molid (int): Molecule ID to cancel loading on";
00329 static PyObject* py_mol_cancel(PyObject *self, PyObject *args, PyObject *kwargs)
00330 {
00331 const char *kwlist[] = {"molid", NULL};
00332 int molid;
00333
00334 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.cancel",
00335 (char**) kwlist, &molid))
00336 return NULL;
00337
00338 VMDApp *app;
00339 if (!(app = get_vmdapp()))
00340 return NULL;
00341
00342 if (!valid_molid(molid, app))
00343 return NULL;
00344
00345 app->molecule_cancel_io(molid);
00346
00347 Py_INCREF(Py_None);
00348 return Py_None;
00349 }
00350
00351 static const char mol_delete_doc[] =
00352 "Delete a molecule\n\n"
00353 "Args:\n"
00354 " molid (int): Molecule ID to delete";
00355 static PyObject* py_mol_delete(PyObject *self, PyObject *args, PyObject *kwargs)
00356 {
00357 const char *kwlist[] = {"molid", NULL};
00358 int molid;
00359
00360 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.delete",
00361 (char**) kwlist, &molid))
00362 return NULL;
00363
00364 VMDApp *app;
00365 if (!(app = get_vmdapp()))
00366 return NULL;
00367
00368 if (!valid_molid(molid, app))
00369 return NULL;
00370
00371 app->molecule_delete(molid);
00372
00373 Py_INCREF(Py_None);
00374 return Py_None;
00375 }
00376
00377 static const char get_top_doc[] =
00378 "Get the ID of the top molecule\n\n"
00379 "Returns:\n"
00380 " (int): Molecule ID of top molecule";
00381 static PyObject* py_get_top(PyObject *self, PyObject *args) {
00382 VMDApp *app;
00383 if (!(app = get_vmdapp()))
00384 return NULL;
00385
00386 return as_pyint(app->molecule_top());
00387 }
00388
00389 static const char set_top_doc[] =
00390 "Set the top molecule\n\n"
00391 "Args:\n"
00392 " molid (int): Molecule ID of new top molecule";
00393 static PyObject* py_set_top(PyObject *self, PyObject *args, PyObject *kwargs) {
00394 const char *kwlist[] = {"molid", NULL};
00395 int molid;
00396
00397 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.set_top",
00398 (char**) kwlist, &molid))
00399 return NULL;
00400
00401 VMDApp *app;
00402 if (!(app = get_vmdapp()))
00403 return NULL;
00404
00405 if (!valid_molid(molid, app))
00406 return NULL;
00407
00408 app->molecule_make_top(molid);
00409
00410 Py_INCREF(Py_None);
00411 return Py_None;
00412 }
00413
00414 static const char mol_read_doc[] =
00415 "Read coordinate data into an existing molecule\n\n"
00416 "Args:\n"
00417 " molid (int): Molecule ID to read data into\n"
00418 " filetype (str): File type of coordinate data\n"
00419 " filename (str): Path to coordinate data\n"
00420 " first (int): First frame to read. Defaults to 0 (first frame)\n"
00421 " last (int): Last frame to read, or -1 for the end. Defaults to -1\n"
00422 " stride (int): Frame stride. Defaults to 1 (read all frames)\n"
00423 " waitfor (int): Number of frames to load before returning. Defaults to 1,\n"
00424 " then loads asyncronously in background. Set to -1 to load all frames\n"
00425 " volsets (list of int): Indices of volumetric datasets to read in from\n"
00426 " the file. Invalid indices will be ignored.";
00427 static PyObject* py_mol_read(PyObject *self, PyObject *args, PyObject *kwargs)
00428 {
00429 const char *kwlist[] = {"molid", "filetype", "filename", "first", "last",
00430 "stride", "waitfor", "volsets", NULL};
00431 PyObject *volsets = NULL;
00432 char *filename, *type;
00433 int molid, rc;
00434 FileSpec spec;
00435
00436
00437 spec.first = 0;
00438 spec.last = -1;
00439 spec.stride = 1;
00440 spec.waitfor = FileSpec::WAIT_BACK;
00441
00442
00443 handle_legacy_keywords(kwargs);
00444
00445 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iss|iiiiO!:molecule.read",
00446 (char**) kwlist, &molid, &type, &filename,
00447 &spec.first, &spec.last, &spec.stride,
00448 &spec.waitfor, &PyList_Type, &volsets))
00449 return NULL;
00450
00451 VMDApp *app;
00452 if (!(app = get_vmdapp()))
00453 return NULL;
00454
00455
00456 if (volsets) {
00457 spec.nvolsets = PyList_Size(volsets);
00458 spec.setids = new int[spec.nvolsets];
00459
00460 for (int i=0; i<spec.nvolsets; i++) {
00461 spec.setids[i] = as_int(PyList_GET_ITEM(volsets, i));
00462 if (PyErr_Occurred())
00463 goto failure;
00464 }
00465
00466
00467
00468
00469 } else {
00470 spec.nvolsets = 1;
00471 spec.setids = new int[1];
00472 spec.setids[0] = 0;
00473 }
00474
00475
00476 rc = app->molecule_load(molid, filename, type, &spec);
00477 if (rc < 0) {
00478 PyErr_Format(PyExc_RuntimeError, "Unable to read filename '%s' "
00479 "format '%s'", filename, type);
00480 goto failure;
00481 }
00482
00483 return as_pyint(rc);
00484
00485 failure:
00486 delete [] spec.setids;
00487 spec.setids = NULL;
00488 return NULL;
00489 }
00490
00491 static const char mol_write_doc[] =
00492 "Write coordinate and topology data from a loaded molecule to a file\n\n"
00493 "Args:\n"
00494 " molid (int): Molecule ID to read data into\n"
00495 " filetype (str): File type of coordinate data\n"
00496 " filename (str): Path to coordinate data\n"
00497 " first (int): First frame to read. Defaults to 0 (first frame)\n"
00498 " last (int): Last frame to read, or -1 for the end. Defaults to -1\n"
00499 " stride (int): Frame stride. Defaults to 1 (write all frames)\n"
00500 " waitfor (int): Number of frames to wait for before returning control. Defaults to -1 (wait for all frames)"
00501 " selection (atomsel): Atom indices to write. Defaults to all atoms."
00502 "Returns:\n"
00503 " (int): Number of frames written";
00504 static PyObject* py_mol_write(PyObject *self, PyObject *args, PyObject *kwargs)
00505 {
00506 const char *kwlist[] = {"molid", "filetype", "filename", "first", "last",
00507 "stride", "waitfor", "selection", NULL};
00508 PyObject *selobj = NULL;
00509 char *filename, *type;
00510 int numframes, molid;
00511 int *on = NULL;
00512 FileSpec spec;
00513 Molecule *mol;
00514
00515
00516 spec.first = 0;
00517 spec.last = -1;
00518 spec.stride = 1;
00519 spec.waitfor = FileSpec::WAIT_ALL;
00520
00521
00522 handle_legacy_keywords(kwargs);
00523
00524 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iss|iiiiO:molecule.write",
00525 (char**) kwlist, &molid, &type, &filename,
00526 &spec.first, &spec.last, &spec.stride, &spec.waitfor,
00527 &selobj))
00528 return NULL;
00529
00530 VMDApp *app;
00531 if (!(app = get_vmdapp()))
00532 return NULL;
00533
00534 if (!valid_molid(molid, app))
00535 return NULL;
00536
00537
00538 mol = app->moleculeList->mol_from_id(molid);
00539 if (spec.first >= mol->numframes() || spec.last >= mol->numframes()
00540 || spec.first < -1 || spec.last < -1) {
00541 PyErr_Format(PyExc_ValueError, "frames '%d-%d' out of bounds for molecule "
00542 "'%d'", spec.first, spec.last, molid);
00543 return NULL;
00544 }
00545
00546
00547 if (selobj && selobj != Py_None) {
00548 AtomSel *sel = atomsel_AsAtomSel( selobj );
00549 if (!sel || sel->molid() != molid) {
00550 PyErr_SetString(PyExc_ValueError, "Atomsel must be valid and must "
00551 "reference same molecule as coordinates");
00552 return NULL;
00553 }
00554 on = sel->on;
00555 }
00556 spec.selection = on;
00557
00558 numframes = app->molecule_savetrajectory(molid, filename, type, &spec);
00559 if (numframes < 0) {
00560 PyErr_Format(PyExc_ValueError, "Unable to save file '%s'", filename);
00561 return NULL;
00562 }
00563
00564 return as_pyint(numframes);
00565 }
00566
00567 static const char numframes_doc[] =
00568 "Get the number of loaded frames in a molecule\n\n"
00569 "Args:\n"
00570 " molid (int): Molecule ID to query\n"
00571 "Returns:\n"
00572 " (int): Number of loaded frames";
00573 static PyObject* py_numframes(PyObject *self, PyObject *args, PyObject *kwargs)
00574 {
00575 const char *kwlist[] = {"molid", NULL};
00576 int molid;
00577
00578 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.numframes",
00579 (char**) kwlist, &molid))
00580 return NULL;
00581
00582 VMDApp *app;
00583 if (!(app = get_vmdapp()))
00584 return NULL;
00585
00586 if (!valid_molid(molid, app))
00587 return NULL;
00588
00589 return as_pyint(app->molecule_numframes(molid));
00590 }
00591
00592 static const char get_frame_doc[] =
00593 "Get the current frame\n\n"
00594 "Args:\n"
00595 " molid (int): Molecule ID to query\n"
00596 "Returns:\n"
00597 " (int): Current frame of molecule";
00598 static PyObject* py_get_frame(PyObject *self, PyObject *args, PyObject *kwargs)
00599 {
00600 const char *kwlist[] = {"molid", NULL};
00601 int molid;
00602
00603 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.get_frame",
00604 (char**) kwlist, &molid))
00605 return NULL;
00606
00607 VMDApp *app;
00608 if (!(app = get_vmdapp()))
00609 return NULL;
00610
00611 if (!valid_molid(molid, app))
00612 return NULL;
00613
00614 return as_pyint(app->molecule_frame(molid));
00615 }
00616
00617 static const char set_frame_doc[] =
00618 "Set the frame of a molecule\n\n"
00619 "Args:\n"
00620 " molid (int): Molecule ID to set\n"
00621 " frame (int): New frame for molecule";
00622 static PyObject* py_set_frame(PyObject *self, PyObject *args, PyObject *kwargs)
00623 {
00624 const char *kwlist[] = {"molid", "frame", NULL};
00625 int molid, frame;
00626
00627 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:molecule.set_frame",
00628 (char**) kwlist, &molid, &frame))
00629 return NULL;
00630
00631 VMDApp *app;
00632 if (!(app = get_vmdapp()))
00633 return NULL;
00634
00635 if (!valid_molid(molid, app))
00636 return NULL;
00637
00638 Molecule *mol = app->moleculeList->mol_from_id(molid);
00639
00640
00641 if (frame < 0 || frame >= mol->numframes()) {
00642 PyErr_Format(PyExc_ValueError, "frame '%d' out of bounds for molecule '%d'",
00643 frame, molid);
00644 return NULL;
00645 }
00646
00647 mol->override_current_frame(frame);
00648 mol->change_ts();
00649
00650 Py_INCREF(Py_None);
00651 return Py_None;
00652 }
00653
00654 static const char delframe_doc[] =
00655 "Delete a frame or frame(s) from a loaded molecule\n\n"
00656 "Args:\n"
00657 " molid (int): Molecule ID to delete frames from\n"
00658 " first (int): First frame to delete, inclusive. Defaults to 0.\n"
00659 " last (int): Last frame to delete, inclusive. Defaults to -1 (last frame)\n"
00660 " stride (int): Keep every Nth frame in range to delete. Defaults to 0.";
00661 static PyObject* py_delframe(PyObject *self, PyObject *args, PyObject *kwargs)
00662 {
00663 const char *kwlist[] = {"molid", "first", "last", "stride", NULL};
00664 int molid = 0, beg=0, end=-1, skip=0;
00665
00666
00667 handle_legacy_keywords(kwargs);
00668
00669 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:molecule.delframe",
00670 (char**) kwlist, &molid, &beg, &end, &skip))
00671 return NULL;
00672
00673
00674 handle_legacy_keywords(kwargs);
00675
00676 VMDApp *app;
00677 if (!(app = get_vmdapp()))
00678 return NULL;
00679
00680 if (!valid_molid(molid, app))
00681 return NULL;
00682
00683 if (!app->molecule_deleteframes(molid, beg, end, skip)) {
00684 PyErr_SetString(PyExc_ValueError, "Unable to delete frames");
00685 return NULL;
00686 }
00687
00688 Py_INCREF(Py_None);
00689 return Py_None;
00690 }
00691
00692 static const char dupframe_doc[] =
00693 "Duplicate a frame.\n\n"
00694 "Args:\n"
00695 " molid (int): Molecule ID to duplicate frames on. If there are no loaded\n"
00696 " frames in this molecule, a new frame with all zero coordinates will\n"
00697 " be created.\n"
00698 " frame (int): Frame to duplicate. Defaults to -1 (current frame)";
00699 static PyObject* py_dupframe(PyObject *self, PyObject *args, PyObject *kwargs)
00700 {
00701 const char *kwlist[] = {"molid", "frame", NULL};
00702 int frame = -1;
00703 int molid;
00704
00705 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i:molecule.dupframe",
00706 (char**) kwlist, &molid, &frame))
00707 return NULL;
00708
00709 VMDApp *app;
00710 if (!(app = get_vmdapp()))
00711 return NULL;
00712
00713 if (!valid_molid(molid, app))
00714 return NULL;
00715
00716 if (!app->molecule_dupframe(molid, frame)) {
00717 PyErr_Format(PyExc_ValueError, "Unable to duplicate frame '%d' in "
00718 "molid '%d'", frame, molid);
00719 return NULL;
00720 }
00721
00722 Py_INCREF(Py_None);
00723 return Py_None;
00724 }
00725
00726 static const char mol_ssrecalc_doc[] =
00727 "Recalculate secondary structure for molecule\n\n"
00728 "Args:\n"
00729 " molid (int): Molecule ID\n"
00730 "Raises:\n"
00731 " RuntimeError: If structure could not be calculated, usually due to the\n"
00732 " Stride program being unavailable";
00733 static PyObject *py_mol_ssrecalc(PyObject *self, PyObject *args,
00734 PyObject *kwargs) {
00735 const char *kwlist[] = {"molid", NULL};
00736 int molid, rc;
00737
00738 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.ssrecalc",
00739 (char**) kwlist, &molid))
00740 return NULL;
00741
00742 VMDApp *app;
00743 if (!(app = get_vmdapp()))
00744 return NULL;
00745
00746 if (!valid_molid(molid, app))
00747 return NULL;
00748
00749
00750 Py_BEGIN_ALLOW_THREADS
00751 rc = app->molecule_ssrecalc(molid);
00752 Py_END_ALLOW_THREADS
00753
00754 if (!rc) {
00755 PyErr_Format(PyExc_RuntimeError, "Secondary structure could not be "
00756 "calculated for molid '%d'", molid);
00757 return NULL;
00758 }
00759
00760 Py_INCREF(Py_None);
00761 return Py_None;
00762 }
00763
00764 static const char mol_rename_doc[] =
00765 "Change the name of a molecule\n\n"
00766 "Args:\n"
00767 " molid (int): Molecule ID to rename\n"
00768 " name (str): New name for molecule";
00769 static PyObject* py_mol_rename(PyObject *self, PyObject *args, PyObject *kwargs)
00770 {
00771 const char *kwlist[] = {"molid", "name", NULL};
00772 char *newname;
00773 int molid;
00774
00775 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "is:molecule.rename",
00776 (char**) kwlist, &molid, &newname))
00777 return NULL;
00778
00779 VMDApp *app;
00780 if (!(app = get_vmdapp()))
00781 return NULL;
00782
00783 if (!valid_molid(molid, app))
00784 return NULL;
00785
00786 if (!app->molecule_rename(molid, newname)) {
00787 PyErr_Format(PyExc_ValueError, "Unable to rename molecule '%d'", molid);
00788 return NULL;
00789 }
00790
00791 Py_INCREF(Py_None);
00792 return Py_None;
00793 }
00794
00795 static const char add_volumetric_doc[] =
00796 "Add a new volumetric dataset to a molecule\n\n"
00797 "Args:\n"
00798 " molid (int): Molecule ID to add dataset to\n"
00799 " name (str): Dataset name\n"
00800 " size (3-tuple of int): Size of grid data in X, Y, and Z dimensions\n"
00801 " data (list of float): Grid data, of length xsize * ysize * zsize\n"
00802 " origin (3-tuple of float): (x,y,z) coordinate of grid origin, at lower left\n"
00803 " rear corner of grid. Defaults to (0,0,0)\n"
00804 " xaxis (3-tuple of float): (x,y,z) vector for X axis. Defaults to (1,0,0)\n"
00805 " yaxis (3-tuple of float): (x,y,z) vector for Y axis. Defaults to (0,1,0)\n"
00806 " zaxis (3-tuple of float): (x,y,z) vector for Z axis. Defaults to (0,0,1)";
00807 static PyObject *py_mol_add_volumetric(PyObject *self, PyObject *args,
00808 PyObject *kwargs) {
00809 const char *kwlist[] = {"molid", "name", "size", "data",
00810 "origin", "xaxis", "yaxis", "zaxis", NULL};
00811 float forigin[3] = {0.f, 0.f, 0.f};
00812 float fxaxis[3] = {1.f, 0.f, 0.f};
00813 float fyaxis[3] = {0.f, 1.f, 0.f};
00814 float fzaxis[3] = {0.f, 0.f, 1.f};
00815 PyObject *seqdata = NULL;
00816 float *fdata = NULL;
00817 int totalsize, i;
00818 PyObject *data;
00819 int molid = -1;
00820 int size[3];
00821 char *name;
00822
00823
00824 if (kwargs && PyDict_GetItemString(kwargs, "xsize")
00825 && PyDict_GetItemString(kwargs, "ysize")
00826 && PyDict_GetItemString(kwargs, "zsize")) {
00827
00828 data = Py_BuildValue("(OOO)", PyDict_GetItemString(kwargs, "xsize"),
00829 PyDict_GetItemString(kwargs, "ysize"),
00830 PyDict_GetItemString(kwargs, "zsize"));
00831
00832 PyDict_DelItemString(kwargs, "xsize");
00833 PyDict_DelItemString(kwargs, "ysize");
00834 PyDict_DelItemString(kwargs, "zsize");
00835
00836 PyDict_SetItemString(kwargs, "size", data);
00837 Py_DECREF(data);
00838
00839 PyErr_Warn(PyExc_DeprecationWarning, "xsize, ysize, zsize keywords are "
00840 "deprecated, pass size as a tuple instead");
00841 }
00842
00843 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
00844 "is(iii)O|O&O&O&O&:molecule.add_volumetric",
00845 (char**) kwlist, &molid, &name, &size[0],
00846 &size[1], &size[2], &data,
00847 &py_array_from_obj, &forigin,
00848 &py_array_from_obj, &fxaxis,
00849 &py_array_from_obj, &fyaxis,
00850 &py_array_from_obj, &fzaxis))
00851 return NULL;
00852
00853 VMDApp *app;
00854 if (!(app = get_vmdapp()))
00855 return NULL;
00856
00857 if (!valid_molid(molid, app))
00858 return NULL;
00859
00860
00861 if (size[0] < 1 || size[1] < 1 || size[2] < 1) {
00862 PyErr_SetString(PyExc_ValueError, "Volumetric sizes must be >= 1");
00863 goto failure;
00864 }
00865
00866
00867 if (!(seqdata = PySequence_Fast(data, "data must be a list or tuple")))
00868 goto failure;
00869
00870 totalsize = size[0] * size[1] * size[2];
00871 if (PyList_Size(data) != totalsize) {
00872 PyErr_Format(PyExc_ValueError, "size of data list '%ld' does not match "
00873 "expected grid size %d x %d x %d",
00874 PySequence_Fast_GET_SIZE(seqdata),
00875 size[0], size[1], size[2]);
00876 goto failure;
00877 }
00878
00879
00880 fdata = new float[totalsize];
00881 for (i = 0; i < totalsize; i++) {
00882 PyObject *elem = PySequence_Fast_GET_ITEM(seqdata, i);
00883
00884 if (!PyFloat_Check(elem)) {
00885 PyErr_SetString(PyExc_TypeError, "Volumetric data must be floats");
00886 goto failure;
00887 }
00888
00889 float tmp = PyFloat_AsDouble(elem);
00890
00891 if (PyErr_Occurred())
00892 goto failure;
00893
00894 fdata[i] = tmp;
00895 }
00896
00897 if (!app->molecule_add_volumetric(molid, name, forigin, fxaxis, fyaxis,
00898 fzaxis, size[0], size[1], size[2], fdata)) {
00899 PyErr_Format(PyExc_ValueError, "Unable to add volumetric data to molid %d",
00900 molid);
00901 goto failure;
00902 }
00903
00904 Py_DECREF(seqdata);
00905 Py_INCREF(Py_None);
00906 return Py_None;
00907
00908 failure:
00909 Py_XDECREF(seqdata);
00910 if (fdata)
00911 delete [] fdata;
00912 return NULL;
00913 }
00914
00915 static const char del_volumetric_doc[] =
00916 "Delete a volumetric dataset from a molecule\n\n"
00917 "Args:\n"
00918 " molid (int): Molecule ID to remove dataset from\n"
00919 " dataindex (int): Volumetric dataset index to delete";
00920 static PyObject* py_mol_del_volumetric(PyObject *self, PyObject *args,
00921 PyObject *kwargs)
00922 {
00923 const char *kwlist[] = {"molid", "dataindex", NULL};
00924 int molid, index;
00925
00926 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:molecule.delete_volumetric",
00927 (char**) kwlist, &molid, &index))
00928 return NULL;
00929
00930 VMDApp *app;
00931 if (!(app = get_vmdapp()))
00932 return NULL;
00933
00934 if (!valid_molid(molid, app))
00935 return NULL;
00936
00937 Molecule *mol = app->moleculeList->mol_from_id(molid);
00938 if (index < 0 || index >= mol->num_volume_data()) {
00939 PyErr_Format(PyExc_ValueError, "Invalid volumetric index '%d'", index);
00940 return NULL;
00941 }
00942
00943 mol->remove_volume_data(index);
00944 Py_INCREF(Py_None);
00945 return Py_None;
00946 }
00947
00948
00949 static PyObject *py_mol_drm_volumetric(PyObject *self, PyObject *args,
00950 PyObject *kwargs) {
00951 PyErr_Warn(PyExc_DeprecationWarning, "the 'remove_volumetric' method has "
00952 "been renamed to 'delete_volumetric'");
00953 return py_mol_del_volumetric(self, args, kwargs);
00954 }
00955
00956 static const char get_volumetric_doc[] =
00957 "Obtain a volumetric dataset loaded into a molecule\n\n"
00958 "Args:\n"
00959 " molid (int): Molecule ID to query\n"
00960 " dataindex (int): Volumetric dataset index to obtain\n"
00961 "Returns:\n"
00962 " (4-list): Dataset, consisting of 4 lists:\n"
00963 " 1.) A 1-D list of the values at each point\n"
00964 " 2.) 3-tuple of int describing the x, y, z lengths.\n"
00965 " 3.) 3-tuple of float describing the position of the origin.\n"
00966 " 4.) 9-tuple of float describing the deltas for the x, y, and z axes)."
00967 "\n\n"
00968 "Example usage for export to numpy:\n"
00969 " >>> data, shape, origin, delta = molecule.get_volumetric(0,0)\n"
00970 " >>> data = np.array(data)\n"
00971 " >>> shape = np.array(shape)\n"
00972 " >>> data = data.reshape(shape, order='F')\n"
00973 " >>> delta = np.array(delta).reshape(3,3)\n"
00974 " >>> delta /= shape-1";
00975 static PyObject* py_mol_get_volumetric(PyObject *self, PyObject *args,
00976 PyObject *kwargs)
00977 {
00978 const char *kwlist[] = {"molid", "dataindex", NULL};
00979 PyObject *result = NULL, *deltas = NULL, *origin = NULL;
00980 PyObject *size = NULL, *data = NULL;
00981 const VolumetricData *synthvol;
00982 int molid, index, dsize, i;
00983
00984 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:molecule.get_volumetric",
00985 (char**) kwlist, &molid, &index))
00986 return NULL;
00987
00988 VMDApp *app;
00989 if (!(app = get_vmdapp()))
00990 return NULL;
00991
00992 if (!valid_molid(molid, app))
00993 return NULL;
00994
00995 Molecule *mol = app->moleculeList->mol_from_id(molid);
00996 if (index < 0 || index >= mol->num_volume_data()) {
00997 PyErr_Format(PyExc_ValueError, "Invalid volumetric index '%d'", index);
00998 return NULL;
00999 }
01000
01001
01002 synthvol = mol->get_volume_data(index);
01003 dsize = synthvol->xsize * synthvol->ysize * synthvol->zsize;
01004
01005
01006 result = PyList_New(4);
01007 deltas = PyTuple_New(9);
01008 origin = PyTuple_New(3);
01009 size = PyTuple_New(3);
01010 data = PyList_New(dsize);
01011
01012 if (!result || !deltas || !origin || !size || !data) {
01013 PyErr_Format(PyExc_MemoryError, "Cannot allocate volumetric data arrays "
01014 "for molid %d volindex %d", molid, index);
01015 goto failure;
01016 }
01017
01018
01019 for (i = 0; i < dsize; i++) {
01020 if (PyList_SetItem(data, i, PyFloat_FromDouble(synthvol->data[i]))) {
01021 PyErr_Format(PyExc_RuntimeError, "Cannot build data array for molid %d "
01022 "volindex %d", molid, index);
01023 goto failure;
01024 }
01025 }
01026
01027
01028 if (PyTuple_SetItem(size, 0, as_pyint(synthvol->xsize))
01029 || PyTuple_SetItem(size, 1, as_pyint(synthvol->ysize))
01030 || PyTuple_SetItem(size, 2, as_pyint(synthvol->zsize))) {
01031 PyErr_Format(PyExc_RuntimeError, "Cannot build box size list for molid %d "
01032 "volindex %d", molid, index);
01033 goto failure;
01034 }
01035
01036
01037 for (i = 0; i < 3; i++) {
01038 if (PyTuple_SetItem(deltas, i, PyFloat_FromDouble(synthvol->xaxis[i]))
01039 || PyTuple_SetItem(deltas, 3+i, PyFloat_FromDouble(synthvol->yaxis[i]))
01040 || PyTuple_SetItem(deltas, 6+i, PyFloat_FromDouble(synthvol->zaxis[i]))
01041 || PyTuple_SetItem(origin, i, PyFloat_FromDouble(synthvol->origin[i]))) {
01042 PyErr_Format(PyExc_RuntimeError, "Cannot build axis vector list for molid"
01043 " %d volindex %d", molid, index);
01044 goto failure;
01045 }
01046 }
01047
01048
01049 PyList_SET_ITEM(result, 0, data);
01050 PyList_SET_ITEM(result, 1, size);
01051 PyList_SET_ITEM(result, 2, origin);
01052 PyList_SET_ITEM(result, 3, deltas);
01053
01054 if (PyErr_Occurred()) {
01055 PyErr_Format(PyExc_RuntimeError, "Problem building volumetric information "
01056 "list for molid %d volindex %d", molid, index);
01057 goto failure;
01058 }
01059
01060 return result;
01061
01062 failure:
01063 Py_XDECREF(data);
01064 Py_XDECREF(deltas);
01065 Py_XDECREF(origin);
01066 Py_XDECREF(size);
01067 Py_XDECREF(result);
01068 return NULL;
01069 }
01070
01071 static const char num_volumetric_doc[] =
01072 "Get the number of volumetric datasets loaded into a molecule\n\n"
01073 "Args:\n"
01074 " molid (int): Molecule ID to query\n"
01075 "Returns:\n"
01076 " (int): Number of volumetric datasets loaded";
01077 static PyObject* py_mol_num_volumetric(PyObject *self, PyObject *args,
01078 PyObject *kwargs)
01079 {
01080 const char *kwlist[] = {"molid", NULL};
01081 int molid;
01082
01083 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.num_volumetric",
01084 (char**) kwlist, &molid))
01085 return NULL;
01086
01087 VMDApp *app;
01088 if (!(app = get_vmdapp()))
01089 return NULL;
01090
01091 if (!valid_molid(molid, app))
01092 return NULL;
01093
01094 Molecule *mol = app->moleculeList->mol_from_id(molid);
01095 return as_pyint(mol->num_volume_data());
01096 }
01097
01098
01099 static const char filenames_doc[] =
01100 "Get list of all files loaded into a molecule\n\n"
01101 "Args:\n"
01102 " molid (int): Molecule ID to query\n"
01103 "Returns:\n"
01104 " (list of str): Paths to files loaded in molecule";
01105 static PyObject* py_get_filenames(PyObject *self, PyObject *args,
01106 PyObject *kwargs)
01107 {
01108 const char *kwlist[] = {"molid", NULL};
01109 PyObject *result;
01110 int molid;
01111
01112 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.get_filenames",
01113 (char**) kwlist, &molid))
01114 return NULL;
01115
01116 VMDApp *app;
01117 if (!(app = get_vmdapp()))
01118 return NULL;
01119
01120 if (!valid_molid(molid, app))
01121 return NULL;
01122
01123 Molecule *mol = app->moleculeList->mol_from_id(molid);
01124
01125 result = PyList_New(mol->num_files());
01126 for (int i=0; i<mol->num_files(); i++) {
01127 PyList_SET_ITEM(result, i, as_pystring(mol->get_file(i)));
01128
01129 if (PyErr_Occurred()) {
01130 PyErr_Format(PyExc_RuntimeError, "Problem listing loaded files in molid "
01131 "'%d'", molid);
01132 Py_DECREF(result);
01133 return NULL;
01134 }
01135 }
01136 return result;
01137 }
01138
01139 static const char filetypes_doc[] =
01140 "Get file types loaded into a molecule\n\n"
01141 "Args:\n"
01142 " molid (int): Molecule ID to query\n"
01143 "Returns:\n"
01144 " (list of str): File types loaded into molecule";
01145 static PyObject* py_get_filetypes(PyObject *self, PyObject *args,
01146 PyObject *kwargs)
01147 {
01148 const char *kwlist[] = {"molid", NULL};
01149 PyObject *result;
01150 int molid;
01151
01152 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.get_filetypes",
01153 (char**) kwlist, &molid))
01154 return NULL;
01155
01156 VMDApp *app;
01157 if (!(app = get_vmdapp()))
01158 return NULL;
01159
01160 if (!valid_molid(molid, app))
01161 return NULL;
01162
01163 Molecule *mol = app->moleculeList->mol_from_id(molid);
01164 result = PyList_New(mol->num_files());
01165
01166 for (int i=0; i<mol->num_files(); i++) {
01167 PyList_SET_ITEM(result, i, as_pystring(mol->get_type(i)));
01168
01169
01170 if (PyErr_Occurred()) {
01171 PyErr_Format(PyExc_RuntimeError, "Problem listing filetypes in molid "
01172 "'%d'", molid);
01173 Py_DECREF(result);
01174 return NULL;
01175 }
01176
01177 }
01178 return result;
01179 }
01180
01181 static const char databases_doc[] =
01182 "Get databases associated with files loaded into a molecule\n\n"
01183 "Args:\n"
01184 " molid (int): Molecule ID to query\n"
01185 "Returns:\n"
01186 " (list of str): Databases loaded into molecule. If no database is\n"
01187 " associated with a given file loaded into the molecule, an empty\n"
01188 " list will be returned";
01189 static PyObject* py_get_databases(PyObject *self, PyObject *args,
01190 PyObject *kwargs)
01191 {
01192 const char *kwlist[] = {"molid", NULL};
01193 PyObject *result;
01194 int molid;
01195
01196 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.get_databases",
01197 (char**) kwlist, &molid))
01198 return NULL;
01199
01200 VMDApp *app;
01201 if (!(app = get_vmdapp()))
01202 return NULL;
01203
01204 if (!valid_molid(molid, app))
01205 return NULL;
01206
01207 Molecule *mol = app->moleculeList->mol_from_id(molid);
01208 result = PyList_New(mol->num_files());
01209
01210 for (int i=0; i<mol->num_files(); i++) {
01211 PyList_SET_ITEM(result, i, as_pystring(mol->get_database(i)));
01212
01213
01214 if (PyErr_Occurred()) {
01215 PyErr_Format(PyExc_RuntimeError, "Problem listing databases in molid "
01216 "'%d'", molid);
01217 Py_DECREF(result);
01218 return NULL;
01219 }
01220 }
01221 return result;
01222 }
01223
01224 static const char accessions_doc[] =
01225 "Get database accession codes associated with files loaded into a molecule\n\n"
01226 "Args:\n"
01227 " molid (int): Molecule ID to query\n"
01228 "Returns:\n"
01229 " (list of str): Accession codes loaded into molecule. If no accession is\n"
01230 " associated with a given file loaded into the molecule, an empty\n"
01231 " list will be returned.";
01232 static PyObject* py_get_accessions(PyObject *self, PyObject *args,
01233 PyObject *kwargs)
01234 {
01235 const char *kwlist[] = {"molid", NULL};
01236 PyObject *result;
01237 int molid;
01238
01239 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.get_accessions",
01240 (char**) kwlist, &molid))
01241 return NULL;
01242
01243 VMDApp *app;
01244 if (!(app = get_vmdapp()))
01245 return NULL;
01246
01247 if (!valid_molid(molid, app))
01248 return NULL;
01249
01250 Molecule *mol = app->moleculeList->mol_from_id(molid);
01251 result = PyList_New(mol->num_files());
01252
01253 for (int i=0; i<mol->num_files(); i++) {
01254 PyList_SET_ITEM(result, i, as_pystring(mol->get_accession(i)));
01255
01256
01257 if (PyErr_Occurred()) {
01258 PyErr_Format(PyExc_RuntimeError, "Problem listing databases in molid "
01259 "'%d'", molid);
01260 Py_DECREF(result);
01261 return NULL;
01262 }
01263 }
01264 return result;
01265 }
01266
01267 static const char remarks_doc[] =
01268 "Get remarks associated with files loaded into a molecule\n\n"
01269 "Args:\n"
01270 " molid (int): Molecule ID to query\n"
01271 "Returns:\n"
01272 " (list of str): Remarks present in the molecule, one string per loaded\n"
01273 " file with remark information. Multiple remarks in the same file will\n"
01274 " be separated by newline (\\n) characters. If no remarks are\n"
01275 " associated with a given file loaded into the molecule, an empty\n"
01276 " string will be present in the list. If no remarks are associated\n"
01277 " with the molecule, an empty list will be returned.";
01278 static PyObject* py_get_remarks(PyObject *self, PyObject *args,
01279 PyObject *kwargs)
01280 {
01281 const char *kwlist[] = {"molid", NULL};
01282 PyObject *result;
01283 int molid;
01284
01285 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:molecule.get_remarks",
01286 (char**) kwlist, &molid))
01287 return NULL;
01288
01289 VMDApp *app;
01290 if (!(app = get_vmdapp()))
01291 return NULL;
01292
01293 if (!valid_molid(molid, app))
01294 return NULL;
01295
01296 Molecule *mol = app->moleculeList->mol_from_id(molid);
01297 result = PyList_New(mol->num_files());
01298
01299 for (int i=0; i<mol->num_files(); i++) {
01300 PyList_SET_ITEM(result, i, as_pystring(mol->get_remarks(i)));
01301
01302
01303 if (PyErr_Occurred()) {
01304 PyErr_Format(PyExc_RuntimeError, "Problem listing remarks in molid '%d'",
01305 molid);
01306 Py_DECREF(result);
01307 return NULL;
01308 }
01309 }
01310 return result;
01311 }
01312
01313
01314 static const char get_periodic_doc[] =
01315 "Get the periodic cell layout\n\n"
01316 "Args:\n"
01317 " molid (int): Molecule ID to query. Defaults to -1 (top molecule)\n"
01318 " frame (int): Frame to get box information from. Defaults to -1 (current)\n"
01319 "Returns:\n"
01320 " (dict str->float): Periodic cell layout with values for keys 'a', 'b',\n"
01321 " and 'c' representing the lengths of the unit cell along the first,\n"
01322 " second, and third unit cell vectors, respectively. Values for keys\n"
01323 " 'alpha', 'beta', and 'gamma' give the angle between sides B and C,\n"
01324 " A and C, and A and B, respectively.";
01325 static PyObject* py_get_periodic(PyObject *self, PyObject *args,
01326 PyObject *kwargs)
01327 {
01328 const char *kwlist[] = {"molid", "frame", NULL};
01329 int molid=-1, frame=-1;
01330 PyObject *dict;
01331
01332 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:molecule.get_periodic",
01333 (char**) kwlist, &molid, &frame))
01334 return NULL;
01335
01336 VMDApp *app;
01337 if (!(app = get_vmdapp()))
01338 return NULL;
01339
01340 if (molid == -1)
01341 molid = app->molecule_top();
01342 if (!valid_molid(molid, app))
01343 return NULL;
01344
01345
01346 Timestep *ts = parse_timestep(app, molid, frame);
01347 if (!ts)
01348 return NULL;
01349
01350 dict = PyDict_New();
01351 PyDict_SetItemString(dict, "a", PyFloat_FromDouble(ts->a_length));
01352 PyDict_SetItemString(dict, "b", PyFloat_FromDouble(ts->b_length));
01353 PyDict_SetItemString(dict, "c", PyFloat_FromDouble(ts->c_length));
01354 PyDict_SetItemString(dict, "alpha", PyFloat_FromDouble(ts->alpha));
01355 PyDict_SetItemString(dict, "beta", PyFloat_FromDouble(ts->beta));
01356 PyDict_SetItemString(dict, "gamma", PyFloat_FromDouble(ts->gamma));
01357
01358
01359 if (PyErr_Occurred()) {
01360 PyErr_SetString(PyExc_RuntimeError, "Problem getting box info");
01361 Py_DECREF(dict);
01362 return NULL;
01363 }
01364
01365 return dict;
01366 }
01367
01368 static const char set_periodic_doc[] =
01369 "Set the periodic cell layout for a particular frame. Any number of box\n"
01370 "attributes may be changed at a time\n\n"
01371 "Args:\n"
01372 " molid (int): Molecule ID. Defaults to -1 (top molecule)\n"
01373 " frame (int): Frame to change box info for. Defaults to -1 (current)\n"
01374 " a (float): Length of unit cell along first cell vector. Optional\n"
01375 " b (float): Length of unit cell along second cell vector. Optional\n"
01376 " c (float): Length of unit cell along third cell vector. Optional\n"
01377 " alpha (float): Angle between cell sides B and C. Optional\n"
01378 " beta (float): Angle between cell sides A and C. Optional\n"
01379 " gamma (float): Angle between cell sides A and B. Optional";
01380 static PyObject *py_set_periodic(PyObject *self, PyObject *args,
01381 PyObject *kwargs)
01382 {
01383 const char *kwlist[] = {"molid", "frame", "a", "b", "c", "alpha", "beta",
01384 "gamma", NULL};
01385 float a=-1, b=-1, c=-1, alpha=-1, beta=-1, gamma=-1;
01386 int molid = -1, frame = -1;
01387
01388 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
01389 "|iiffffff:molecule.set_periodic",
01390 (char**) kwlist, &molid, &frame, &a, &b,
01391 &c, &alpha, &beta, &gamma))
01392 return NULL;
01393
01394 VMDApp *app;
01395 if (!(app = get_vmdapp()))
01396 return NULL;
01397
01398 if (molid == -1)
01399 molid = app->molecule_top();
01400 if (!valid_molid(molid, app))
01401 return NULL;
01402
01403 Timestep *ts = parse_timestep(app, molid, frame);
01404 if (!ts)
01405 return NULL;
01406
01407 if (a >= 0)
01408 ts->a_length = a;
01409 if (b >= 0)
01410 ts->b_length = b;
01411 if (c >= 0)
01412 ts->c_length = c;
01413 if (alpha > 0)
01414 ts->alpha = alpha;
01415 if (beta > 0)
01416 ts->beta = beta;
01417 if (gamma > 0)
01418 ts->gamma = gamma;
01419
01420 Py_INCREF(Py_None);
01421 return Py_None;
01422 }
01423
01424 static const char get_visible_doc[] =
01425 "Get if a molecule is visible\n\n"
01426 "Args:\n"
01427 " molid (int): Molecule ID to query. Defaults to -1 (top molecule)\n"
01428 "Returns:\n"
01429 " (bool): If molecule is visible";
01430 static PyObject* py_get_visible(PyObject *self, PyObject *args,PyObject *kwargs)
01431 {
01432 const char *kwlist[] = {"molid", NULL};
01433 int molid = -1;
01434
01435 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:molecule.get_visible",
01436 (char**) kwlist, &molid))
01437 return NULL;
01438
01439 VMDApp *app;
01440 if (!(app = get_vmdapp()))
01441 return NULL;
01442
01443 if (molid<0)
01444 molid = app->molecule_top();
01445 if (!valid_molid(molid, app))
01446 return NULL;
01447
01448 return PyBool_FromLong(app->molecule_is_displayed(molid));
01449 }
01450
01451 static const char set_visible_doc[] =
01452 "Set the visiblity of a molecule\n\n"
01453 "Args:\n"
01454 " molid (int): Molecule ID\n"
01455 " visible (bool): If molecule should be visible";
01456 static PyObject* py_set_visible(PyObject *self, PyObject *args,
01457 PyObject *kwargs)
01458 {
01459 const char *kwlist[] = {"molid", "visible", NULL};
01460 PyObject *value;
01461 int molid = -1;
01462 int visible;
01463
01464
01465 if (kwargs && (value = PyDict_GetItemString(kwargs, "state"))) {
01466 PyDict_SetItemString(kwargs, "visible", value);
01467 PyDict_DelItemString(kwargs, "state");
01468 PyErr_Warn(PyExc_DeprecationWarning, "'state' keywords is 'visible' now");
01469 }
01470
01471 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|O&:molecule.set_visible",
01472 (char**) kwlist, &molid, convert_bool,
01473 &visible))
01474 return NULL;
01475
01476 VMDApp *app;
01477 if (!(app = get_vmdapp()))
01478 return NULL;
01479
01480 if (!valid_molid(molid, app))
01481 return NULL;
01482
01483 app->molecule_display(molid, visible);
01484 Py_INCREF(Py_None);
01485 return Py_None;
01486 }
01487
01488 static const char time_doc[] =
01489 "Get the physical time value for a frame, if set\n\n"
01490 "Args:\n"
01491 " molid (int): Molecule ID to query\n"
01492 " frame (int): Frame to query. Defaults to -1 (current)\n"
01493 "Returns:\n"
01494 " (float): Physical time value for frame, or 0.0f if unset";
01495 static PyObject* py_get_physical_time(PyObject *self, PyObject *args,
01496 PyObject *kwargs)
01497 {
01498 const char *kwlist[] = {"molid", "frame", NULL};
01499 int molid = -1, frame = -1;
01500
01501 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
01502 "i|i:molecule.get_physical_time",
01503 (char**) kwlist, &molid, &frame))
01504 return NULL;
01505
01506 VMDApp *app;
01507 if (!(app = get_vmdapp()))
01508 return NULL;
01509
01510 if (!valid_molid(molid, app))
01511 return NULL;
01512
01513 Timestep *ts = parse_timestep(app, molid, frame);
01514 if (!ts)
01515 return NULL;
01516
01517 return PyFloat_FromDouble(ts->physical_time);
01518 }
01519
01520 static const char settime_doc[] =
01521 "Set the physical time value for a frame\n\n"
01522 "Args:\n"
01523 " molid (int): Molecule ID to set time for.\n"
01524 " time (float): Time value\n"
01525 " frame (int): Frame to set time for. Defaults to -1 (current)\n";
01526 static PyObject* py_set_physical_time(PyObject *self, PyObject *args,
01527 PyObject *kwargs)
01528 {
01529 const char *kwlist[] = {"molid", "time", "frame", NULL};
01530 int molid = -1, frame = -1;
01531 double value;
01532
01533 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
01534 "id|i:molecule.set_physical_time",
01535 (char**) kwlist, &molid, &value, &frame))
01536 return NULL;
01537
01538 VMDApp *app;
01539 if (!(app = get_vmdapp()))
01540 return NULL;
01541
01542 if (!valid_molid(molid, app))
01543 return NULL;
01544
01545 Timestep *ts = parse_timestep(app, molid, frame);
01546 if (!ts)
01547 return NULL;
01548
01549 ts->physical_time = value;
01550
01551 Py_INCREF(Py_None);
01552 return Py_None;
01553 }
01554
01555 static PyMethodDef methods[] = {
01556 {"num", (PyCFunction)py_mol_num, METH_NOARGS, mol_num_doc },
01557 {"listall", (PyCFunction)py_mol_listall, METH_VARARGS | METH_KEYWORDS ,mol_listall_doc},
01558 {"exists", (PyCFunction)py_mol_exists, METH_VARARGS | METH_KEYWORDS, mol_exists_doc},
01559 {"name", (PyCFunction)py_mol_name, METH_VARARGS | METH_KEYWORDS, mol_name_doc},
01560 {"numatoms", (PyCFunction)py_mol_numatoms, METH_VARARGS | METH_KEYWORDS, mol_numatoms_doc},
01561 {"new", (PyCFunction)py_mol_new, METH_VARARGS | METH_KEYWORDS, mol_new_doc},
01562 {"fromsel", (PyCFunction)py_mol_fromsel, METH_VARARGS | METH_KEYWORDS, mol_fromsel_doc},
01563 {"load", (PyCFunction)py_mol_load, METH_VARARGS | METH_KEYWORDS, mol_load_doc},
01564 {"cancel", (PyCFunction)py_mol_cancel, METH_VARARGS | METH_KEYWORDS, mol_cancel_doc},
01565 {"delete", (PyCFunction)py_mol_delete, METH_VARARGS | METH_KEYWORDS, mol_delete_doc},
01566 {"get_top", (PyCFunction)py_get_top, METH_NOARGS, get_top_doc},
01567 {"set_top", (PyCFunction)py_set_top, METH_VARARGS | METH_KEYWORDS, set_top_doc},
01568 {"read", (PyCFunction)py_mol_read, METH_VARARGS | METH_KEYWORDS, mol_read_doc},
01569 {"write", (PyCFunction)py_mol_write, METH_VARARGS | METH_KEYWORDS, mol_write_doc},
01570 {"numframes", (PyCFunction)py_numframes, METH_VARARGS | METH_KEYWORDS, numframes_doc},
01571 {"get_frame", (PyCFunction)py_get_frame, METH_VARARGS | METH_KEYWORDS, get_frame_doc},
01572 {"set_frame", (PyCFunction)py_set_frame, METH_VARARGS | METH_KEYWORDS, set_frame_doc},
01573 {"delframe", (PyCFunction)py_delframe, METH_VARARGS | METH_KEYWORDS, delframe_doc},
01574 {"dupframe", (PyCFunction)py_dupframe, METH_VARARGS | METH_KEYWORDS, dupframe_doc},
01575 {"ssrecalc", (PyCFunction)py_mol_ssrecalc, METH_VARARGS | METH_KEYWORDS, mol_ssrecalc_doc},
01576 {"rename", (PyCFunction)py_mol_rename, METH_VARARGS | METH_KEYWORDS, mol_rename_doc},
01577 {"add_volumetric", (PyCFunction)py_mol_add_volumetric,
01578 METH_VARARGS | METH_KEYWORDS, add_volumetric_doc},
01579 {"delete_volumetric", (PyCFunction)py_mol_del_volumetric,
01580 METH_VARARGS | METH_KEYWORDS, del_volumetric_doc},
01581 {"get_volumetric", (PyCFunction)py_mol_get_volumetric,
01582 METH_VARARGS | METH_KEYWORDS, get_volumetric_doc},
01583 {"num_volumetric", (PyCFunction)py_mol_num_volumetric,
01584 METH_VARARGS | METH_KEYWORDS, num_volumetric_doc},
01585 {"get_filenames", (PyCFunction)py_get_filenames, METH_VARARGS | METH_KEYWORDS, filenames_doc},
01586 {"get_filetypes", (PyCFunction)py_get_filetypes, METH_VARARGS | METH_KEYWORDS, filetypes_doc},
01587 {"get_databases", (PyCFunction)py_get_databases, METH_VARARGS | METH_KEYWORDS, databases_doc},
01588 {"get_accessions", (PyCFunction)py_get_accessions, METH_VARARGS | METH_KEYWORDS, accessions_doc},
01589 {"get_remarks", (PyCFunction)py_get_remarks, METH_VARARGS | METH_KEYWORDS, remarks_doc},
01590 {"get_periodic", (PyCFunction)py_get_periodic, METH_VARARGS | METH_KEYWORDS, get_periodic_doc},
01591 {"set_periodic", (PyCFunction)py_set_periodic, METH_VARARGS | METH_KEYWORDS, set_periodic_doc},
01592 {"get_visible", (PyCFunction)py_get_visible, METH_VARARGS | METH_KEYWORDS, get_visible_doc},
01593 {"set_visible", (PyCFunction)py_set_visible, METH_VARARGS | METH_KEYWORDS, set_visible_doc},
01594 {"get_physical_time", (PyCFunction)py_get_physical_time, METH_VARARGS | METH_KEYWORDS, time_doc},
01595 {"set_physical_time", (PyCFunction)py_set_physical_time, METH_VARARGS | METH_KEYWORDS, settime_doc},
01596
01597
01598 {"remove_volumetric", (PyCFunction)py_mol_drm_volumetric,
01599 METH_VARARGS | METH_KEYWORDS, del_volumetric_doc},
01600 {NULL, NULL}
01601 };
01602
01603 static const char mol_moddoc[] =
01604 "Methods to interact with molecules, including loading topology, trajectory, "
01605 "or volumetric data, query the attributes of a molecule such as the number "
01606 "of frames or the physical time, or set the visibility of a molecule";
01607
01608 #if PY_MAJOR_VERSION >= 3
01609 static struct PyModuleDef moleculedef = {
01610 PyModuleDef_HEAD_INIT,
01611 "molecule",
01612 mol_moddoc,
01613 -1,
01614 methods,
01615 };
01616 #endif
01617
01618 PyObject* initmolecule(void) {
01619 #if PY_MAJOR_VERSION >= 3
01620 PyObject *module = PyModule_Create(&moleculedef);
01621 #else
01622 PyObject *module = Py_InitModule3("molecule", methods, mol_moddoc);
01623 #endif
01624 return module;
01625 }
01626