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
00023 #ifdef VMDIMD
00024
00025 #include "CmdIMD.h"
00026 #include "CommandQueue.h"
00027 #include "VMDApp.h"
00028 #include "MoleculeList.h"
00029 #include "IMDMgr.h"
00030
00031 static const char connect_doc[] =
00032 "Connect to an IMD server\n\n"
00033 "Args:\n"
00034 " host (str): Server hostname\n"
00035 " port (int): Port running IMD server";
00036 static PyObject* py_imdconnect(PyObject *self, PyObject *args, PyObject *kwargs) {
00037 const char *kwlist[] = {"host", "port", NULL};
00038 char *host;
00039 int port;
00040
00041 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si:imd.connect",
00042 (char**) kwlist, &host, &port))
00043 return NULL;
00044
00045 VMDApp *app;
00046 if (!(app = get_vmdapp()))
00047 return NULL;
00048
00049 Molecule *mol = app->moleculeList->top();
00050 if (!mol) {
00051 PyErr_SetString(PyExc_ValueError, "No molecule loaded");
00052 return NULL;
00053 }
00054
00055 if (app->imdMgr->connected()) {
00056 PyErr_SetString(PyExc_ValueError, "Can't create new IMD connection: "
00057 "already connected.");
00058 return NULL;
00059 }
00060
00061 if (!app->imd_connect(mol->id(), host, port)) {
00062 PyErr_Format(PyExc_RuntimeError, "Unable to connect to IMD server '%s:%d'",
00063 host, port);
00064 return NULL;
00065 }
00066
00067 Py_INCREF(Py_None);
00068 return Py_None;
00069 }
00070
00071
00072 static const char pause_doc[] =
00073 "Pause a running IMD simulation";
00074 static PyObject* py_imdpause(PyObject *self, PyObject *args) {
00075 VMDApp *app;
00076 if (!(app = get_vmdapp()))
00077 return NULL;
00078
00079 if (!app->imdMgr->connected()) {
00080 PyErr_SetString(PyExc_ValueError, "Not connected to an IMD server");
00081 return NULL;
00082 }
00083
00084 app->imdMgr->togglepause();
00085 app->commandQueue->runcommand(new CmdIMDSim(CmdIMDSim::PAUSE_TOGGLE));
00086
00087 Py_INCREF(Py_None);
00088 return Py_None;
00089 }
00090
00091
00092 static const char detach_doc[] =
00093 "Detach from a running IMD simulation";
00094 static PyObject *py_imddetach(PyObject *self, PyObject *args) {
00095 VMDApp *app;
00096 if (!(app = get_vmdapp()))
00097 return NULL;
00098
00099 if (!app->imdMgr->connected()) {
00100 PyErr_SetString(PyExc_ValueError, "Not connected to an IMD server");
00101 return NULL;
00102 }
00103
00104 app->imdMgr->detach();
00105 app->commandQueue->runcommand(new CmdIMDSim(CmdIMDSim::DETACH));
00106
00107 Py_INCREF(Py_None);
00108 return Py_None;
00109 }
00110
00111
00112 static const char kill_doc[] =
00113 "Halt a running IMD simulation. Also detaches.";
00114 static PyObject* py_imdkill(PyObject *self, PyObject *args) {
00115 VMDApp *app;
00116 if (!(app = get_vmdapp()))
00117 return NULL;
00118
00119 if (!app->imdMgr->connected()) {
00120 PyErr_SetString(PyExc_ValueError, "Not connected to an IMD server");
00121 return NULL;
00122 }
00123
00124 app->imdMgr->kill();
00125 app->commandQueue->runcommand(new CmdIMDSim(CmdIMDSim::KILL));
00126
00127 Py_INCREF(Py_None);
00128 return Py_None;
00129 }
00130
00131
00132 static const char transfer_doc[] =
00133 "Get and/or set how often timesteps are sent to the IMD server\n\n"
00134 "Args:\n"
00135 " rate (int): New transfer rate, or None to query. Rate must be greater\n"
00136 " than 0\n"
00137 "Returns:\n"
00138 " (int): Updated transfer rate";
00139 static PyObject* py_imdtransfer(PyObject *self, PyObject *args,
00140 PyObject *kwargs) {
00141 const char *kwlist[] = {"rate", NULL};
00142 PyObject *rateobj = NULL;
00143 int rate;
00144
00145 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:imd.transfer",
00146 (char**) kwlist, &rateobj))
00147 return NULL;
00148
00149 VMDApp *app;
00150 if (!(app = get_vmdapp()))
00151 return NULL;
00152
00153 if (rateobj) {
00154 rate = as_int(rateobj);
00155
00156 if (rate <= 0) {
00157 PyErr_SetString(PyExc_ValueError, "transfer rate must be > 0");
00158 return NULL;
00159 }
00160
00161 app->imdMgr->set_trans_rate(rate);
00162 app->commandQueue->runcommand(new CmdIMDRate(CmdIMDRate::TRANSFER, rate));
00163 }
00164
00165 return as_pyint(app->imdMgr->get_trans_rate());
00166 }
00167
00168
00169 static const char keep_doc[] =
00170 "Get and/or set how often timesteps are saved.\n\n"
00171 "Args:\n"
00172 " rate (int): Save frequency, or None to query. Rate must be greater than\n"
00173 " or equal to 0\n"
00174 "Returns:\n"
00175 " (int): Updated save frequency";
00176 static PyObject* py_imdkeep(PyObject *self, PyObject *args, PyObject *kwargs) {
00177 const char *kwlist[] = {"rate", NULL};
00178 PyObject *rateobj = NULL;
00179 int rate;
00180
00181 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:imd.keep",
00182 (char**) kwlist, &rateobj))
00183 return NULL;
00184
00185 VMDApp *app;
00186 if (!(app = get_vmdapp()))
00187 return NULL;
00188
00189 if (rateobj) {
00190 rate = as_int(rateobj);
00191
00192 if (rate < 0) {
00193 PyErr_SetString(PyExc_ValueError, "keep value must be >= 0");
00194 return NULL;
00195 }
00196
00197 app->imdMgr->set_keep_rate(rate);
00198 app->commandQueue->runcommand(new CmdIMDRate(CmdIMDRate::KEEP, rate));
00199 }
00200
00201 return as_pyint(app->imdMgr->get_keep_rate());
00202 }
00203
00204
00205 static const char copy_doc[] =
00206 "Set if unit cell information should be copied from previous frame\n\n"
00207 "Args:\n"
00208 " copy (bool): If cell information should be copied";
00209 static PyObject* py_copyunitcell(PyObject *self, PyObject *args,
00210 PyObject *kwargs) {
00211 const char *kwlist[] = {"copy", NULL};
00212 CmdIMDCopyUnitCell::CmdIMDCopyUnitCellCommand c;
00213 int copy;
00214
00215 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:imd.copyunitcell",
00216 (char**) kwlist, convert_bool, ©))
00217 return NULL;
00218
00219 VMDApp *app;
00220 if (!(app = get_vmdapp()))
00221 return NULL;
00222
00223 app->imdMgr->set_copyunitcell(copy);
00224 c = copy ? CmdIMDCopyUnitCell::COPYCELL_ON : CmdIMDCopyUnitCell::COPYCELL_OFF;
00225 app->commandQueue->runcommand(new CmdIMDCopyUnitCell(c));
00226
00227 Py_INCREF(Py_None);
00228 return Py_None;
00229 }
00230
00231
00232 static const char connected_doc[] =
00233 "Query if an IMD connection exists\n\n"
00234 "Returns:\n"
00235 " (bool): True if a connection exists, False otherwise";
00236 static PyObject* py_imdconnected(PyObject *self, PyObject *args) {
00237 VMDApp *app;
00238 if (!(app = get_vmdapp()))
00239 return NULL;
00240
00241 PyObject *result = app->imdMgr->connected() ? Py_True : Py_False;
00242 Py_INCREF(result);
00243 return result;
00244 }
00245
00246
00247 static PyMethodDef methods[] = {
00248 {"connected", (PyCFunction)py_imdconnected, METH_NOARGS, connected_doc},
00249 {"connect", (PyCFunction)py_imdconnect, METH_VARARGS | METH_KEYWORDS, connect_doc},
00250 {"pause", (PyCFunction)py_imdpause, METH_NOARGS, pause_doc},
00251 {"detach", (PyCFunction)py_imddetach, METH_NOARGS, detach_doc},
00252 {"kill", (PyCFunction)py_imdkill, METH_NOARGS, kill_doc},
00253 {"transfer", (PyCFunction)py_imdtransfer, METH_VARARGS | METH_KEYWORDS, transfer_doc},
00254 {"keep", (PyCFunction)py_imdkeep, METH_VARARGS | METH_KEYWORDS, keep_doc},
00255 {"copyunitcell", (PyCFunction)py_copyunitcell, METH_VARARGS | METH_KEYWORDS, copy_doc},
00256 {NULL, NULL}
00257 };
00258
00259
00260 static const char imd_moddoc[] =
00261 "Methods for controlling interactive molecular dynamics simulations";
00262
00263
00264 #if PY_MAJOR_VERSION >= 3
00265 static struct PyModuleDef imddef = {
00266 PyModuleDef_HEAD_INIT,
00267 "imd",
00268 imd_moddoc,
00269 -1,
00270 methods,
00271 };
00272 #endif
00273
00274
00275 PyObject* initimd() {
00276 #if PY_MAJOR_VERSION >= 3
00277 PyObject *m = PyModule_Create(&imddef);
00278 #else
00279 PyObject *m = Py_InitModule3("imd", methods, imd_moddoc);
00280 #endif
00281 return m;
00282 }
00283
00284 #endif
00285