00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <tcl.h>
00025 #include <ctype.h>
00026 #include <math.h>
00027 #include "TclCommands.h"
00028 #include "AtomSel.h"
00029 #include "Matrix4.h"
00030 #include "SymbolTable.h"
00031 #include "VMDApp.h"
00032 #include "MoleculeList.h"
00033 #include "utilities.h"
00034 #include "config.h"
00035 #include "Measure.h"
00036 #include "MeasureSymmetry.h"
00037 #include "SpatialSearch.h"
00038 #include "Atom.h"
00039 #include "Molecule.h"
00040
00041
00042 #include "QuickSurf.h"
00043 #include "MDFF.h"
00044 #include "CUDAMDFF.h"
00045 #include "MeasureVolInterior.h"
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 int tcl_get_weights(Tcl_Interp *interp, VMDApp *app, AtomSel *sel,
00058 Tcl_Obj *weight_obj, float *data) {
00059 char *weight_string = NULL;
00060
00061 if (!sel) return MEASURE_ERR_NOSEL;
00062 if (!app->molecule_valid_id(sel->molid())) return MEASURE_ERR_NOMOLECULE;
00063 if (weight_obj)
00064 weight_string = Tcl_GetStringFromObj(weight_obj, NULL);
00065
00066 if (!weight_string || !strcmp(weight_string, "none")) {
00067 for (int i=0; i<sel->selected; i++) {
00068 data[i] = 1.0;
00069 }
00070 return MEASURE_NOERR;
00071 }
00072
00073
00074 SymbolTable *atomSelParser = app->atomSelParser;
00075
00076
00077
00078 atomsel_ctxt context(atomSelParser,
00079 app->moleculeList->mol_from_id(sel->molid()),
00080 sel->which_frame, NULL);
00081
00082 int fctn = atomSelParser->find_attribute(weight_string);
00083 if (fctn >= 0) {
00084
00085 if (atomSelParser->fctns.data(fctn)->returns_a != SymbolTableElement::IS_FLOAT) {
00086 Tcl_AppendResult(interp,
00087 "weight attribute must have floating point values", NULL);
00088 return MEASURE_ERR_BADWEIGHTPARM;
00089 }
00090
00091 double *tmp_data = new double[sel->num_atoms];
00092 atomSelParser->fctns.data(fctn)->keyword_double(&context,
00093 sel->num_atoms, tmp_data, sel->on);
00094
00095 for (int i=sel->firstsel, j=0; i<=sel->lastsel; i++) {
00096 if (sel->on[i])
00097 data[j++] = (float)tmp_data[i];
00098 }
00099
00100 delete [] tmp_data;
00101 return MEASURE_NOERR;
00102 }
00103
00104
00105 int list_num;
00106 Tcl_Obj **list_data;
00107 if (Tcl_ListObjGetElements(interp, weight_obj, &list_num, &list_data)
00108 != TCL_OK) {
00109 return MEASURE_ERR_BADWEIGHTPARM;
00110 }
00111 if (list_num != sel->selected && list_num != sel->num_atoms)
00112 return MEASURE_ERR_BADWEIGHTNUM;
00113
00114 for (int i=0, j=0; i<list_num; i++) {
00115 double tmp_data;
00116
00117 if (Tcl_GetDoubleFromObj(interp, list_data[i], &tmp_data) != TCL_OK)
00118 return MEASURE_ERR_NONNUMBERPARM;
00119
00120 if (list_num == sel->selected) {
00121 data[i] = (float)tmp_data;
00122 } else {
00123 if (sel->on[i]) {
00124 data[j++] = (float)tmp_data;
00125 }
00126 }
00127 }
00128
00129 return MEASURE_NOERR;
00130 }
00131
00132
00133 int atomsel_default_weights(AtomSel *sel, float *weights) {
00134 if (sel->firstsel > 0)
00135 memset(&weights[0], 0, sel->firstsel * sizeof(float));
00136
00137 for (int i=sel->firstsel; i<=sel->lastsel; i++) {
00138
00139 weights[i] = sel->on[i] ? 1.0f : 0.0f;
00140 }
00141
00142 if (sel->lastsel < (sel->num_atoms - 1))
00143 memset(&weights[sel->lastsel+1], 0, ((sel->num_atoms - 1) - sel->lastsel) * sizeof(float));
00144
00145 return 0;
00146 }
00147
00148
00149 int get_weights_from_tcl_list(Tcl_Interp *interp, VMDApp *app, AtomSel *sel,
00150 Tcl_Obj *weights_obj, float *weights) {
00151 int list_num = 0;
00152 Tcl_Obj **list_elems = NULL;
00153 if (Tcl_ListObjGetElements(interp, weights_obj, &list_num, &list_elems)
00154 != TCL_OK) {
00155 return MEASURE_ERR_BADWEIGHTPARM;
00156 }
00157 if (list_num != sel->num_atoms) {
00158 return MEASURE_ERR_BADWEIGHTNUM;
00159 }
00160 for (int i = 0; i < sel->num_atoms; i++) {
00161 double tmp_data = 0.0;
00162 if (Tcl_GetDoubleFromObj(interp, list_elems[i], &tmp_data) != TCL_OK) {
00163 return TCL_ERROR;
00164 }
00165 weights[i] = static_cast<float>(tmp_data);
00166 }
00167 return 0;
00168 }
00169
00170
00171
00172
00173
00174 int get_attribute_index(VMDApp *app, char const *string) {
00175 SymbolTable *atomSelParser = app->atomSelParser;
00176 return atomSelParser->find_attribute(string);
00177 }
00178
00179
00180 int get_weights_from_attribute(VMDApp *app, AtomSel *sel,
00181 char const *weights_string, float *weights) {
00182 SymbolTable *atomSelParser = app->atomSelParser;
00183 int fctn = atomSelParser->find_attribute(weights_string);
00184
00185
00186 if (atomSelParser->fctns.data(fctn)->returns_a !=
00187 SymbolTableElement::IS_FLOAT) {
00188 return MEASURE_ERR_BADWEIGHTPARM;
00189 }
00190 atomsel_ctxt context(atomSelParser,
00191 app->moleculeList->mol_from_id(sel->molid()),
00192 sel->which_frame, NULL);
00193 double *tmp_data = new double[sel->num_atoms];
00194 atomSelParser->fctns.data(fctn)->keyword_double(&context, sel->num_atoms,
00195 tmp_data, sel->on);
00196
00197 if (sel->firstsel > 0)
00198 memset(&weights[0], 0, sel->firstsel * sizeof(float));
00199
00200 for (int i=sel->firstsel; i<=sel->lastsel; i++) {
00201 weights[i] = sel->on[i] ? static_cast<float>(tmp_data[i]) : 0.0f;
00202 }
00203
00204 if (sel->lastsel < (sel->num_atoms - 1))
00205 memset(&weights[sel->lastsel+1], 0, ((sel->num_atoms - 1) - sel->lastsel) * sizeof(float));
00206
00207 delete [] tmp_data;
00208 return 0;
00209 }
00210
00211
00212
00213 int tcl_get_orders(Tcl_Interp *interp, int selnum,
00214 Tcl_Obj *order_obj, int *data) {
00215 int list_num;
00216 Tcl_Obj **list_data;
00217
00218 if (Tcl_ListObjGetElements(interp, order_obj, &list_num, &list_data)
00219 != TCL_OK) {
00220 return MEASURE_ERR_NOSEL;
00221 }
00222
00223
00224 if (list_num != selnum) return MEASURE_ERR_NOSEL;
00225
00226 for (int i=0; i<list_num; i++) {
00227 if (Tcl_GetIntFromObj(interp, list_data[i], &data[i]) != TCL_OK)
00228 return MEASURE_ERR_NONNUMBERPARM;
00229
00230
00231 if (data[i] < 0 || data[i] >= selnum)
00232 return MEASURE_ERR_BADORDERINDEX;
00233 }
00234
00235 return MEASURE_NOERR;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 static int vmd_measure_center(VMDApp *app, int argc, Tcl_Obj *const objv[], Tcl_Interp *interp) {
00259 if (argc != 2 && argc != 4 ) {
00260 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<sel> [weight <weights>]");
00261 return TCL_ERROR;
00262 }
00263 if (argc == 4 && strcmp(Tcl_GetStringFromObj(objv[2],NULL), "weight")) {
00264 Tcl_SetResult(interp, (char *) "measure center: parameter can only be 'weight'", TCL_STATIC);
00265 return TCL_ERROR;
00266 }
00267
00268
00269 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
00270 if (!sel) {
00271 Tcl_SetResult(interp, (char *) "measure center: no atom selection", TCL_STATIC);
00272 return TCL_ERROR;
00273 }
00274
00275
00276 float *weight = new float[sel->selected];
00277 int ret_val=0;
00278 if (argc == 2) {
00279 ret_val = tcl_get_weights(interp, app, sel, NULL, weight);
00280 } else {
00281 ret_val = tcl_get_weights(interp, app, sel, objv[3], weight);
00282 }
00283 if (ret_val < 0) {
00284 Tcl_AppendResult(interp, "measure center: ", measure_error(ret_val), NULL);
00285 delete [] weight;
00286 return TCL_ERROR;
00287 }
00288
00289
00290 float com[3];
00291 const float *framepos = sel->coordinates(app->moleculeList);
00292 ret_val = measure_center(sel, framepos, weight, com);
00293 delete [] weight;
00294 if (ret_val < 0) {
00295 Tcl_AppendResult(interp, "measure center: ", measure_error(ret_val), NULL);
00296 return TCL_ERROR;
00297 }
00298
00299 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00300 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(com[0]));
00301 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(com[1]));
00302 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(com[2]));
00303 Tcl_SetObjResult(interp, tcl_result);
00304
00305 return TCL_OK;
00306 }
00307
00308
00309 static int vmd_measure_centerperresidue(VMDApp *app, int argc, Tcl_Obj *const objv[], Tcl_Interp *interp) {
00310 int ret_val = 0;
00311
00312
00313 if (argc != 2 && argc != 4 ) {
00314 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<sel> [weight <weights>]");
00315 return TCL_ERROR;
00316 }
00317
00318
00319 if (argc == 4 && strcmp(Tcl_GetStringFromObj(objv[2], NULL), "weight")) {
00320 Tcl_SetResult(interp, (char *) "measure centerperresidue: parameter can only be 'weight'", TCL_STATIC);
00321 return TCL_ERROR;
00322 }
00323
00324
00325 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1], NULL));
00326 if (!sel) {
00327 Tcl_SetResult(interp, (char *) "measure centerperresidue: no atom selection", TCL_STATIC);
00328 return TCL_ERROR;
00329 }
00330
00331
00332 float *weight = new float[sel->selected];
00333 if (argc == 2) {
00334
00335 ret_val = tcl_get_weights(interp, app, sel, NULL, weight);
00336 } else {
00337
00338 ret_val = tcl_get_weights(interp, app, sel, objv[3], weight);
00339 }
00340 if (ret_val < 0) {
00341 Tcl_AppendResult(interp, "measure centerperresidue: ",
00342 measure_error(ret_val), NULL);
00343 delete [] weight;
00344 return TCL_ERROR;
00345 }
00346
00347
00348 float *com = new float[3*sel->selected];
00349 const float *framepos = sel->coordinates(app->moleculeList);
00350 ret_val = measure_center_perresidue(app->moleculeList, sel,
00351 framepos, weight, com);
00352 delete [] weight;
00353 if (ret_val < 0) {
00354 Tcl_AppendResult(interp, "measure centerperresidue: ",
00355 measure_error(ret_val), NULL);
00356 return TCL_ERROR;
00357 }
00358
00359
00360 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00361 for (int i=0; i<ret_val; i++) {
00362 Tcl_Obj *m = Tcl_NewListObj(0, NULL);
00363 for (int j=0; j<3; j++) {
00364 Tcl_ListObjAppendElement(interp, m, Tcl_NewDoubleObj(com[3*i+j]));
00365 }
00366 Tcl_ListObjAppendElement(interp, tcl_result, m);
00367 }
00368 Tcl_SetObjResult(interp, tcl_result);
00369 delete [] com;
00370
00371 return TCL_OK;
00372 }
00373
00374
00375
00376 static int vmd_measure_sumweights(VMDApp *app, int argc, Tcl_Obj *const objv[], Tcl_Interp *interp) {
00377 if (argc != 4) {
00378 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<sel> weight <weights>");
00379 return TCL_ERROR;
00380 }
00381 if (strcmp(Tcl_GetStringFromObj(objv[2],NULL), "weight")) {
00382 Tcl_SetResult(interp, (char *) "measure sumweights: parameter can only be 'weight'", TCL_STATIC);
00383 return TCL_ERROR;
00384 }
00385
00386
00387 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL)
00388 );
00389 if (!sel) {
00390 Tcl_SetResult(interp, (char *) "measure sumweights: no atom selection", TCL_STATIC);
00391 return TCL_ERROR;
00392 }
00393
00394
00395 float *weight = new float[sel->selected];
00396 int ret_val = 0;
00397 ret_val = tcl_get_weights(interp, app, sel, objv[3], weight);
00398 if (ret_val < 0) {
00399 Tcl_AppendResult(interp, "measure center: ", measure_error(ret_val), NULL);
00400 delete [] weight;
00401 return TCL_ERROR;
00402 }
00403
00404
00405 float weightsum=0;
00406 ret_val = measure_sumweights(sel, sel->selected, weight, &weightsum);
00407 delete [] weight;
00408 if (ret_val < 0) {
00409 Tcl_AppendResult(interp, "measure center: ", measure_error(ret_val), NULL);
00410 return TCL_ERROR;
00411 }
00412
00413 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00414 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(weightsum));
00415 Tcl_SetObjResult(interp, tcl_result);
00416
00417 return TCL_OK;
00418 }
00419
00420
00421
00422
00423
00424 static int vmd_measure_avpos(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00425 int first = 0;
00426 int last = -1;
00427 int step = 1;
00428
00429 if (argc < 2 || argc > 8) {
00430 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<sel> [first <first>] [last <last>] [step <step>]");
00431 return TCL_ERROR;
00432 }
00433 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL)
00434 );
00435 if (!sel) {
00436 Tcl_AppendResult(interp, "measure avpos: no atom selection", NULL);
00437 return TCL_ERROR;
00438 }
00439
00440 int i;
00441 for (i=2; i<argc; i+=2) {
00442 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
00443 if (!strupncmp(argvcur, "first", CMDLEN)) {
00444 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
00445 Tcl_AppendResult(interp, "measure avpos: bad first frame value", NULL);
00446 return TCL_ERROR;
00447 }
00448 } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00449 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
00450 Tcl_AppendResult(interp, "measure avpos: bad last frame value", NULL);
00451 return TCL_ERROR;
00452 }
00453 } else if (!strupncmp(argvcur, "step", CMDLEN)) {
00454 if (Tcl_GetIntFromObj(interp, objv[i+1], &step) != TCL_OK) {
00455 Tcl_AppendResult(interp, "measure avpos: bad frame step value", NULL);
00456 return TCL_ERROR;
00457 }
00458 } else {
00459 Tcl_AppendResult(interp, "measure rmsdmat_qcp: invalid syntax, no such keyword: ", argvcur, NULL);
00460 return TCL_ERROR;
00461 }
00462 }
00463
00464 float *avpos = new float[3L*sel->selected];
00465 int ret_val = measure_avpos(sel, app->moleculeList, first, last, step, avpos);
00466 if (ret_val < 0) {
00467 Tcl_AppendResult(interp, "measure avpos: ", measure_error(ret_val), NULL);
00468 delete [] avpos;
00469 return TCL_ERROR;
00470 }
00471
00472 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00473 for (i=0; i<sel->selected; i++) {
00474 Tcl_Obj *atom = Tcl_NewListObj(0, NULL);
00475 Tcl_ListObjAppendElement(interp, atom, Tcl_NewDoubleObj(avpos[i*3L ]));
00476 Tcl_ListObjAppendElement(interp, atom, Tcl_NewDoubleObj(avpos[i*3L + 1]));
00477 Tcl_ListObjAppendElement(interp, atom, Tcl_NewDoubleObj(avpos[i*3L + 2]));
00478 Tcl_ListObjAppendElement(interp, tcl_result, atom);
00479 }
00480
00481 Tcl_SetObjResult(interp, tcl_result);
00482 delete [] avpos;
00483
00484 return TCL_OK;
00485 }
00486
00487
00488
00489
00490 static int vmd_measure_dipole(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00491 const char *opt;
00492 int unitsdebye=0;
00493 int usecenter=1;
00494
00495 if ((argc < 2) || (argc > 4)) {
00496 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<sel> [-elementary|-debye] [-geocenter|-masscenter|-origincenter]");
00497 return TCL_ERROR;
00498 }
00499 AtomSel *sel;
00500 sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1], NULL));
00501 if (!sel) {
00502 Tcl_AppendResult(interp, "measure dipole: no atom selection", NULL);
00503 return TCL_ERROR;
00504 }
00505
00506 int i;
00507 for (i=0; i < (argc-2); ++i) {
00508 opt = Tcl_GetStringFromObj(objv[2+i], NULL);
00509 if (!strcmp(opt, "-debye"))
00510 unitsdebye=1;
00511 if (!strcmp(opt, "-elementary"))
00512 unitsdebye=0;
00513
00514 if (!strcmp(opt, "-geocenter"))
00515 usecenter=1;
00516 if (!strcmp(opt, "-masscenter"))
00517 usecenter=-1;
00518 if (!strcmp(opt, "-origincenter"))
00519 usecenter=0;
00520 }
00521
00522 float dipole[3];
00523 int ret_val = measure_dipole(sel, app->moleculeList, dipole, unitsdebye, usecenter);
00524 if (ret_val < 0) {
00525 Tcl_AppendResult(interp, "measure dipole: ", measure_error(ret_val), NULL);
00526 return TCL_ERROR;
00527 }
00528
00529 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00530 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(dipole[0]));
00531 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(dipole[1]));
00532 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(dipole[2]));
00533 Tcl_SetObjResult(interp, tcl_result);
00534
00535 return TCL_OK;
00536 }
00537
00538
00539
00540
00541
00542
00543 static int vmd_measure_dihed(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00544 int first=-1, last=-1, frame=-1;
00545 if (argc < 2) {
00546 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "{{<atomid1> [<molid1>]} {<atomid2> [<molid2>]} {<atomid3> [<molid3>]} {<atomid4> [<molid4>]}} [molid <default molid>] [frame <frame|all|last> | first <first> last <last>]");
00547 return TCL_ERROR;
00548 }
00549
00550 int molid[4], atmid[4], defmolid = -1;
00551 bool allframes = false;
00552
00553
00554 char *geomname = Tcl_GetStringFromObj(objv[0],NULL);
00555
00556
00557 int numatms;
00558 Tcl_Obj **data;
00559 if (Tcl_ListObjGetElements(interp, objv[1], &numatms, &data) != TCL_OK) {
00560 Tcl_AppendResult(interp, " measure ", geomname, ": bad syntax", NULL);
00561 Tcl_AppendResult(interp, " Usage: measure ", geomname, " {{<atomid1> [<molid1>]} {<atomid2> [<molid2>]} {<atomid3> [<molid3>]} {<atomid4> [<molid4>]}} [molid <default molid>] [frame <frame|all|last> | first <first> last <last>]", NULL);
00562 return TCL_ERROR;
00563 }
00564
00565 if (numatms != 4) {
00566 Tcl_AppendResult(interp, " measure dihed: must specify exactly four atoms in a list", NULL);
00567 return TCL_ERROR;
00568 }
00569
00570 if (argc > 3) {
00571 int i;
00572 for (i=2; i<argc; i+=2) {
00573 char *argvcur = Tcl_GetStringFromObj(objv[i], NULL);
00574 if (!strupncmp(argvcur, "molid", CMDLEN)) {
00575 if (Tcl_GetIntFromObj(interp, objv[i+1], &defmolid) != TCL_OK) {
00576 Tcl_AppendResult(interp, " measure ", geomname, ": bad molid", NULL);
00577 return TCL_ERROR;
00578 }
00579 } else if (!strupncmp(argvcur, "first", CMDLEN)) {
00580 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
00581 Tcl_AppendResult(interp, " measure ", geomname, ": bad first frame value", NULL);
00582 return TCL_ERROR;
00583 }
00584 } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00585 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
00586 Tcl_AppendResult(interp, " measure ", geomname, ": bad last frame value", NULL);
00587 return TCL_ERROR;
00588 }
00589 } else if (!strupncmp(argvcur, "frame", CMDLEN)) {
00590 if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "all")) {
00591 allframes = true;
00592 } else if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "last")) {
00593 frame=-2;
00594 } else if (Tcl_GetIntFromObj(interp, objv[i+1], &frame) != TCL_OK) {
00595 Tcl_AppendResult(interp, " measure ", geomname, ": bad frame value", NULL);
00596 return TCL_ERROR;
00597 }
00598 } else {
00599 Tcl_AppendResult(interp, "measure ", geomname, ": invalid syntax, no such keyword: ", argvcur, NULL);
00600 return TCL_ERROR;
00601 }
00602 }
00603 }
00604
00605 if ((allframes || frame>=0) && (first>=0 || last>=0)) {
00606 Tcl_AppendResult(interp, "measure ", geomname, ": Ambiguous syntax: You cannot specify a frame AND a frame range (using first or last).", NULL);
00607 Tcl_AppendResult(interp, "\nUsage:\nmeasure ", geomname, " {<atomid1> [<molid1>]} {<atomid2> [<molid2>]} {<atomid3> [<molid3>]} {<atomid4> [<molid4>]}} [molid <default molid>] [frame <frame|all|last> | first <first> last <last>]", NULL);
00608 return TCL_ERROR;
00609 }
00610
00611 if (allframes) first=0;
00612
00613
00614 if (defmolid<0) defmolid = app->molecule_top();
00615
00616
00617 int i,numelem;
00618 Tcl_Obj **atmmol;
00619 for (i=0; i<numatms; i++) {
00620 if (Tcl_ListObjGetElements(interp, data[i], &numelem, &atmmol) != TCL_OK) {
00621 return TCL_ERROR;
00622 }
00623
00624 if (!numelem) {
00625 Tcl_AppendResult(interp, " measure ", geomname, ": empty atom index", NULL);
00626 return TCL_ERROR;
00627 }
00628
00629 if (Tcl_GetIntFromObj(interp, atmmol[0], atmid+i) != TCL_OK) {
00630 Tcl_AppendResult(interp, " measure ", geomname, ": bad atom index", NULL);
00631 return TCL_ERROR;
00632 }
00633
00634 if (numelem==2) {
00635 if (Tcl_GetIntFromObj(interp, atmmol[1], molid+i) != TCL_OK) {
00636 Tcl_AppendResult(interp, " measure ", geomname, ": bad molid", NULL);
00637 return TCL_ERROR;
00638 }
00639 } else molid[i] = defmolid;
00640 }
00641
00642
00643 ResizeArray<float> gValues(1024);
00644 int ret_val;
00645 ret_val = measure_geom(app->moleculeList, molid, atmid, &gValues,
00646 frame, first, last, defmolid, MEASURE_DIHED);
00647 if (ret_val < 0) {
00648 Tcl_AppendResult(interp, measure_error(ret_val), NULL);
00649 return TCL_ERROR;
00650 }
00651
00652 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00653 int numvalues = gValues.num();
00654 for (int count = 0; count < numvalues; count++) {
00655 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(gValues[count]));
00656 }
00657 Tcl_SetObjResult(interp, tcl_result);
00658
00659 return TCL_OK;
00660 }
00661
00662
00663
00664
00665
00666 static int vmd_measure_angle(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00667 int first=-1, last=-1, frame=-1;
00668
00669 if(argc<2) {
00670 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "{{<atomid1> [<molid1>]} {<atomid2> [<molid2>]} {<atomid3> [<molid3>]}} [molid <default molid>] [frame <frame|all|last> | first <first> last <last>]");
00671 return TCL_ERROR;
00672 }
00673
00674 int molid[3], atmid[3], defmolid = -1;
00675 bool allframes = false;
00676
00677
00678 int numatms;
00679 Tcl_Obj **data;
00680 if (Tcl_ListObjGetElements(interp, objv[1], &numatms, &data) != TCL_OK) {
00681 Tcl_AppendResult(interp, " measure bond: bad syntax", NULL);
00682 Tcl_AppendResult(interp, " Usage: measure angle {{<atomid1> [<molid1>]} {<atomid2> [<molid2>]} {<atomid3> [<molid3>]}} [molid <default molid>] [frame <frame|all|last> | first <first> last <last>]", NULL);
00683 return TCL_ERROR;
00684 }
00685
00686 if (numatms != 3) {
00687 Tcl_AppendResult(interp, " measure angle: must specify exactly three atoms in a list", NULL);
00688 return TCL_ERROR;
00689 }
00690
00691 if (argc > 3) {
00692 for (int i=2; i<argc; i+=2) {
00693 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
00694 if (!strupncmp(argvcur, "molid", CMDLEN)) {
00695 if (Tcl_GetIntFromObj(interp, objv[i+1], &defmolid) != TCL_OK) {
00696 Tcl_AppendResult(interp, " measure angle: bad molid", NULL);
00697 return TCL_ERROR;
00698 }
00699 } else if (!strupncmp(argvcur, "first", CMDLEN)) {
00700 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
00701 Tcl_AppendResult(interp, " measure angle: bad first frame value", NULL);
00702 return TCL_ERROR;
00703 }
00704 } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00705 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
00706 Tcl_AppendResult(interp, " measure angle: bad last frame value", NULL);
00707 return TCL_ERROR;
00708 }
00709 } else if (!strupncmp(argvcur, "frame", CMDLEN)) {
00710 if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "all")) {
00711 allframes = true;
00712 } else if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "last")) {
00713 frame=-2;
00714 } else if (Tcl_GetIntFromObj(interp, objv[i+1], &frame) != TCL_OK) {
00715 Tcl_AppendResult(interp, " measure angle: bad frame value", NULL);
00716 return TCL_ERROR;
00717 }
00718 } else {
00719 Tcl_AppendResult(interp, " measure angle: invalid syntax, no such keyword: ", argvcur, NULL);
00720 return TCL_ERROR;
00721 }
00722 }
00723 }
00724
00725 if ((allframes || frame>=0) && (first>=0 || last>=0)) {
00726 Tcl_AppendResult(interp, "measure angle: Ambiguous syntax: You cannot specify a frame AND a frame range (using first or last).", NULL);
00727 Tcl_AppendResult(interp, "\nUsage:\nmeasure angle {<atomid1> [<molid1>]} {<atomid2> [<molid2>]} {<atomid3> [<molid3>]}} [molid <default molid>] [frame <frame|all|last> | first <first> last <last>]", NULL);
00728 return TCL_ERROR;
00729 }
00730
00731 if (allframes) first=0;
00732
00733
00734 if (defmolid<0) defmolid = app->molecule_top();
00735
00736
00737 int i,numelem;
00738 Tcl_Obj **atmmol;
00739 for (i=0; i<numatms; i++) {
00740 if (Tcl_ListObjGetElements(interp, data[i], &numelem, &atmmol) != TCL_OK) {
00741 return TCL_ERROR;
00742 }
00743
00744 if (!numelem) {
00745 Tcl_AppendResult(interp, " measure angle: empty atom index", NULL);
00746 return TCL_ERROR;
00747 }
00748
00749 if (Tcl_GetIntFromObj(interp, atmmol[0], atmid+i) != TCL_OK) {
00750 Tcl_AppendResult(interp, " measure angle: bad atom index", NULL);
00751 return TCL_ERROR;
00752 }
00753
00754 if (numelem==2) {
00755 if (Tcl_GetIntFromObj(interp, atmmol[1], molid+i) != TCL_OK) {
00756 Tcl_AppendResult(interp, " measure angle: bad molid", NULL);
00757 return TCL_ERROR;
00758 }
00759 } else molid[i] = defmolid;
00760 }
00761
00762
00763 ResizeArray<float> gValues(1024);
00764 int ret_val;
00765 ret_val = measure_geom(app->moleculeList, molid, atmid, &gValues,
00766 frame, first, last, defmolid, MEASURE_ANGLE);
00767 if (ret_val<0) {
00768 printf("ERROR\n %s\n", measure_error(ret_val));
00769 Tcl_AppendResult(interp, measure_error(ret_val), NULL);
00770 return TCL_ERROR;
00771 }
00772
00773 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00774 int numvalues = gValues.num();
00775 for (int count = 0; count < numvalues; count++) {
00776 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(gValues[count]));
00777 }
00778 Tcl_SetObjResult(interp, tcl_result);
00779
00780 return TCL_OK;
00781 }
00782
00783
00784
00785
00786 static int vmd_measure_bond(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00787 int first=-1, last=-1, frame=-1;
00788
00789 if (argc<2) {
00790 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "{{<atomid1> [<molid1>]} {<atomid2> [<molid2>]}} [molid <default molid>] [frame <frame|all|last> | first <first> last <last>]]");
00791 return TCL_ERROR;
00792 }
00793
00794 int molid[2], atmid[2], defmolid = -1;
00795 bool allframes = false;
00796
00797
00798 int numatms=0;
00799 Tcl_Obj **data;
00800 if (Tcl_ListObjGetElements(interp, objv[1], &numatms, &data) != TCL_OK) {
00801 Tcl_AppendResult(interp, " measure bond: bad syntax", NULL);
00802 Tcl_AppendResult(interp, " Usage: measure bond {{<atomid1> [<molid1>]} {<atomid2> [<molid2>]}} [molid <default>] [frame <frame|all|last> | first <first> last <last>]]", NULL);
00803 return TCL_ERROR;
00804 }
00805
00806 if (numatms != 2) {
00807 Tcl_AppendResult(interp, " measure bond: must specify exactly two atoms in a list", NULL);
00808 return TCL_ERROR;
00809 }
00810
00811 if (argc > 3) {
00812 for (int i=2; i<argc; i+=2) {
00813 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
00814 if (!strupncmp(argvcur, "molid", CMDLEN)) {
00815 if (Tcl_GetIntFromObj(interp, objv[i+1], &defmolid) != TCL_OK) {
00816 Tcl_AppendResult(interp, " measure bond: bad molid", NULL);
00817 return TCL_ERROR;
00818 }
00819 } else if (!strupncmp(argvcur, "first", CMDLEN)) {
00820 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
00821 Tcl_AppendResult(interp, " measure bond: bad first frame value", NULL);
00822 return TCL_ERROR;
00823 }
00824 } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00825 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
00826 Tcl_AppendResult(interp, " measure bond: bad last frame value", NULL);
00827 return TCL_ERROR;
00828 }
00829 } else if (!strupncmp(argvcur, "frame", CMDLEN)) {
00830 if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "all")) {
00831 allframes = true;
00832 } else if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "last")) {
00833 frame=-2;
00834 } else if (Tcl_GetIntFromObj(interp, objv[i+1], &frame) != TCL_OK) {
00835 Tcl_AppendResult(interp, " measure bond: bad frame value", NULL);
00836 return TCL_ERROR;
00837 }
00838 } else {
00839 Tcl_AppendResult(interp, " measure bond: invalid syntax, no such keyword: ", argvcur, NULL);
00840 return TCL_ERROR;
00841 }
00842 }
00843 }
00844
00845 if ((allframes || frame>=0) && (first>=0 || last>=0)) {
00846 Tcl_AppendResult(interp, "measure bond: Ambiguous syntax: You cannot specify a frame AND a frame range (using first or last).", NULL);
00847 Tcl_AppendResult(interp, "\nUsage:\nmeasure bond {{<atomid1> [<molid1>]} {<atomid2> [<molid2>]}} [molid <default>] [frame <frame|all|last> | first <first> last <last>]", NULL);
00848 return TCL_ERROR;
00849 }
00850
00851 if (allframes) first=0;
00852
00853
00854 if (defmolid<0) defmolid = app->molecule_top();
00855
00856
00857 int i, numelem;
00858 Tcl_Obj **atmmol;
00859 for (i=0; i<numatms; i++) {
00860 if (Tcl_ListObjGetElements(interp, data[i], &numelem, &atmmol) != TCL_OK) {
00861 return TCL_ERROR;
00862 }
00863
00864 if (!numelem) {
00865 Tcl_AppendResult(interp, " measure bond: empty atom index", NULL);
00866 return TCL_ERROR;
00867 }
00868
00869 if (Tcl_GetIntFromObj(interp, atmmol[0], atmid+i) != TCL_OK) {
00870 Tcl_AppendResult(interp, " measure bond: bad atom index", NULL);
00871 return TCL_ERROR;
00872 }
00873
00874 if (numelem==2) {
00875 if (Tcl_GetIntFromObj(interp, atmmol[1], molid+i) != TCL_OK) {
00876 Tcl_AppendResult(interp, " measure bond: bad molid", NULL);
00877 return TCL_ERROR;
00878 }
00879 } else molid[i] = defmolid;
00880 }
00881
00882
00883 ResizeArray<float> gValues(1024);
00884 int ret_val;
00885 ret_val = measure_geom(app->moleculeList, molid, atmid, &gValues,
00886 frame, first, last, defmolid, MEASURE_BOND);
00887 if (ret_val < 0) {
00888 printf("ERROR\n %s\n", measure_error(ret_val));
00889 Tcl_AppendResult(interp, measure_error(ret_val), NULL);
00890 return TCL_ERROR;
00891 }
00892
00893 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00894 int numvalues = gValues.num();
00895 for (int count = 0; count < numvalues; count++) {
00896 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(gValues[count]));
00897 }
00898 Tcl_SetObjResult(interp, tcl_result);
00899
00900 return TCL_OK;
00901 }
00902
00903
00904
00905
00906
00907
00908 static int vmd_measure_rmsfperresidue(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00909 int first = 0;
00910 int last = -1;
00911 int step = 1;
00912
00913 if (argc < 2 || argc > 8) {
00914 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<sel> [first <first>] [last <last>] [step <step>]");
00915 return TCL_ERROR;
00916 }
00917 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL)
00918 );
00919 if (!sel) {
00920 Tcl_AppendResult(interp, "measure rmsfperresidue: no atom selection", NULL);
00921 return TCL_ERROR;
00922 }
00923
00924 int i;
00925 for (i=2; i<argc; i+=2) {
00926 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
00927 if (!strupncmp(argvcur, "first", CMDLEN)) {
00928 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
00929 Tcl_AppendResult(interp, "measure rmsfperresidue: bad first frame value", NULL);
00930 return TCL_ERROR;
00931 }
00932 } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00933 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
00934 Tcl_AppendResult(interp, "measure rmsfperresidue: bad last frame value", NULL);
00935 return TCL_ERROR;
00936 }
00937 } else if (!strupncmp(argvcur, "step", CMDLEN)) {
00938 if (Tcl_GetIntFromObj(interp, objv[i+1], &step) != TCL_OK) {
00939 Tcl_AppendResult(interp, "measure rmsfperresidue: bad frame step value", NULL);
00940 return TCL_ERROR;
00941 }
00942 } else {
00943 Tcl_AppendResult(interp, "measure rmsfperresidue: invalid syntax, no such keyword: ", argvcur, NULL);
00944 return TCL_ERROR;
00945 }
00946 }
00947
00948 float *rmsf = new float[sel->selected];
00949 int ret_val = measure_rmsf_perresidue(sel, app->moleculeList, first, last, step, rmsf);
00950 if (ret_val < 0) {
00951 Tcl_AppendResult(interp, "measure rmsfperresidue: ", measure_error(ret_val), NULL);
00952 delete [] rmsf;
00953 return TCL_ERROR;
00954 }
00955
00956 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00957 for (i=0; i<ret_val; i++) {
00958 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(rmsf[i]));
00959 }
00960 Tcl_SetObjResult(interp, tcl_result);
00961 delete [] rmsf;
00962
00963 return TCL_OK;
00964 }
00965
00966
00967
00968
00969
00970 static int vmd_measure_rmsf(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00971 int first = 0;
00972 int last = -1;
00973 int step = 1;
00974
00975 if (argc < 2 || argc > 8) {
00976 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<sel> [first <first>] [last <last>] [step <step>]");
00977 return TCL_ERROR;
00978 }
00979 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL)
00980 );
00981 if (!sel) {
00982 Tcl_AppendResult(interp, "measure rmsf: no atom selection", NULL);
00983 return TCL_ERROR;
00984 }
00985
00986 int i;
00987 for (i=2; i<argc; i+=2) {
00988 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
00989 if (!strupncmp(argvcur, "first", CMDLEN)) {
00990 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
00991 Tcl_AppendResult(interp, "measure rmsf: bad first frame value", NULL);
00992 return TCL_ERROR;
00993 }
00994 } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00995 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
00996 Tcl_AppendResult(interp, "measure rmsf: bad last frame value", NULL);
00997 return TCL_ERROR;
00998 }
00999 } else if (!strupncmp(argvcur, "step", CMDLEN)) {
01000 if (Tcl_GetIntFromObj(interp, objv[i+1], &step) != TCL_OK) {
01001 Tcl_AppendResult(interp, "measure rmsf: bad frame step value", NULL);
01002 return TCL_ERROR;
01003 }
01004 } else {
01005 Tcl_AppendResult(interp, "measure rmsf: invalid syntax, no such keyword: ", argvcur, NULL);
01006 return TCL_ERROR;
01007 }
01008 }
01009
01010 float *rmsf = new float[sel->selected];
01011 int ret_val = measure_rmsf(sel, app->moleculeList, first, last, step, rmsf);
01012 if (ret_val < 0) {
01013 Tcl_AppendResult(interp, "measure rmsf: ", measure_error(ret_val), NULL);
01014 delete [] rmsf;
01015 return TCL_ERROR;
01016 }
01017
01018 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
01019 for (i=0; i<sel->selected; i++) {
01020 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(rmsf[i]));
01021 }
01022 Tcl_SetObjResult(interp, tcl_result);
01023
01024 delete [] rmsf;
01025 return TCL_OK;
01026 }
01027
01028
01029
01030 static int vmd_measure_rgyr(VMDApp *app, int argc, Tcl_Obj *const objv[], Tcl_Interp *interp) {
01031 if (argc != 2 && argc != 4) {
01032 Tcl_WrongNumArgs(interp, 2, objv-1,
01033 (char *)"<selection> [weight <weights>]");
01034 return TCL_ERROR;
01035 }
01036 if (argc == 4 && strcmp(Tcl_GetStringFromObj(objv[2],NULL), "weight")) {
01037 Tcl_SetResult(interp, (char *) "measure rgyr: parameter can only be 'weight'", TCL_STATIC);
01038 return TCL_ERROR;
01039 }
01040
01041
01042 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
01043 if (!sel) {
01044 Tcl_SetResult(interp, (char *) "measure rgyr: no atom selection", TCL_STATIC);
01045 return TCL_ERROR;
01046 }
01047
01048
01049 float *weight = new float[sel->selected];
01050 int ret_val = 0;
01051 if (argc == 2) {
01052 ret_val = tcl_get_weights(interp, app, sel, NULL, weight);
01053 } else {
01054 ret_val = tcl_get_weights(interp, app, sel, objv[3], weight);
01055 }
01056 if (ret_val < 0) {
01057 Tcl_AppendResult(interp, "measure rgyr: ", measure_error(ret_val), NULL);
01058 delete [] weight;
01059 return TCL_ERROR;
01060 }
01061
01062 float rgyr;
01063 ret_val = measure_rgyr(sel, app->moleculeList, weight, &rgyr);
01064 delete [] weight;
01065 if (ret_val < 0) {
01066 Tcl_AppendResult(interp, "measure rgyr: ", measure_error(ret_val), NULL);
01067 return TCL_ERROR;
01068 }
01069 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rgyr));
01070 return TCL_OK;
01071 }
01072
01073
01074
01075
01076
01077
01078 static int vmd_measure_minmax(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01079 const float *radii = NULL;
01080 if (argc != 2 && argc != 3) {
01081 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<selection> [-withradii]");
01082 return TCL_ERROR;
01083 }
01084 if (argc == 3 && strcmp(Tcl_GetStringFromObj(objv[2],NULL), "-withradii")) {
01085 Tcl_SetResult(interp, (char *) "measure minmax: parameter can only be '-withradii'", TCL_STATIC);
01086 return TCL_ERROR;
01087 }
01088
01089 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
01090 if (!sel) {
01091 Tcl_AppendResult(interp, "measure minmax: no atom selection", NULL);
01092 return TCL_ERROR;
01093 }
01094
01095 float min_coord[3], max_coord[3];
01096 const float *framepos = sel->coordinates(app->moleculeList);
01097 if (!framepos) return TCL_ERROR;
01098
01099
01100 if (argc == 3) {
01101 Molecule *mol = app->moleculeList->mol_from_id(sel->molid());
01102 radii = mol->extraflt.data("radius");
01103 }
01104
01105 int ret_val = measure_minmax(sel->num_atoms, sel->on, framepos, radii,
01106 min_coord, max_coord);
01107 if (ret_val < 0) {
01108 Tcl_AppendResult(interp, "measure minmax: ", measure_error(ret_val), NULL);
01109 return TCL_ERROR;
01110 }
01111
01112 Tcl_Obj *list1 = Tcl_NewListObj(0, NULL);
01113 Tcl_Obj *list2 = Tcl_NewListObj(0, NULL);
01114 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
01115
01116 Tcl_ListObjAppendElement(interp, list1, Tcl_NewDoubleObj(min_coord[0]));
01117 Tcl_ListObjAppendElement(interp, list1, Tcl_NewDoubleObj(min_coord[1]));
01118 Tcl_ListObjAppendElement(interp, list1, Tcl_NewDoubleObj(min_coord[2]));
01119
01120 Tcl_ListObjAppendElement(interp, list2, Tcl_NewDoubleObj(max_coord[0]));
01121 Tcl_ListObjAppendElement(interp, list2, Tcl_NewDoubleObj(max_coord[1]));
01122 Tcl_ListObjAppendElement(interp, list2, Tcl_NewDoubleObj(max_coord[2]));
01123
01124 Tcl_ListObjAppendElement(interp, tcl_result, list1);
01125 Tcl_ListObjAppendElement(interp, tcl_result, list2);
01126 Tcl_SetObjResult(interp, tcl_result);
01127
01128 return TCL_OK;
01129 }
01130
01131
01132 static int vmd_measure_rmsdperresidue(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01133 if (argc !=3 && argc != 5) {
01134 Tcl_WrongNumArgs(interp, 2, objv-1,
01135 (char *)"<sel1> <sel2> [weight <weights>]");
01136 return TCL_ERROR;
01137 }
01138
01139
01140 AtomSel *sel1 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
01141 AtomSel *sel2 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[2],NULL));
01142 if (!sel1 || !sel2) {
01143 Tcl_AppendResult(interp, "measure rmsd: no atom selection", NULL);
01144 return TCL_ERROR;
01145 }
01146
01147 if (sel1->selected != sel2->selected) {
01148 Tcl_AppendResult(interp, "measure rmsd: selections must have the same number of atoms", NULL);
01149 return TCL_ERROR;
01150 }
01151 if (!sel1->selected) {
01152 Tcl_AppendResult(interp, "measure rmsd: no atoms selected", NULL);
01153 return TCL_ERROR;
01154 }
01155 float *weight = new float[sel1->selected];
01156 int ret_val = 0;
01157 if (argc == 3) {
01158 ret_val = tcl_get_weights(interp, app, sel1, NULL, weight);
01159 } else {
01160 ret_val = tcl_get_weights(interp, app, sel1, objv[4], weight);
01161 }
01162 if (ret_val < 0) {
01163 Tcl_AppendResult(interp, "measure rmsd: ", measure_error(ret_val), NULL);
01164 delete [] weight;
01165 return TCL_ERROR;
01166 }
01167
01168
01169 float *rmsd = new float[sel1->selected];
01170 int rc = measure_rmsd_perresidue(sel1, sel2, app->moleculeList,
01171 sel1->selected, weight, rmsd);
01172 if (rc < 0) {
01173 Tcl_AppendResult(interp, "measure rmsd: ", measure_error(rc), NULL);
01174 delete [] weight;
01175 delete [] rmsd;
01176 return TCL_ERROR;
01177 }
01178 delete [] weight;
01179 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
01180 int i;
01181 for (i=0; i<rc; i++) {
01182 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(rmsd[i]));
01183 }
01184 delete [] rmsd;
01185 Tcl_SetObjResult(interp, tcl_result);
01186
01187 return TCL_OK;
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 static int vmd_measure_rmsd(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp)
01209 {
01210 if (argc !=3 && argc != 5) {
01211 Tcl_WrongNumArgs(interp, 2, objv-1,
01212 (char *)"<sel1> <sel2> [weight <weights>]");
01213 return TCL_ERROR;
01214 }
01215
01216
01217 AtomSel *sel1 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
01218 AtomSel *sel2 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[2],NULL));
01219 if (!sel1 || !sel2) {
01220 Tcl_AppendResult(interp, "measure rmsd: no atom selection", NULL);
01221 return TCL_ERROR;
01222 }
01223
01224 if (sel1->selected != sel2->selected) {
01225 Tcl_AppendResult(interp, "measure rmsd: selections must have the same number of atoms", NULL);
01226 return TCL_ERROR;
01227 }
01228 if (!sel1->selected) {
01229 Tcl_AppendResult(interp, "measure rmsd: no atoms selected", NULL);
01230 return TCL_ERROR;
01231 }
01232
01233 float *weight = new float[sel1->selected];
01234 int ret_val = 0;
01235 if (argc == 3) {
01236 ret_val = tcl_get_weights(interp, app, sel1, NULL, weight);
01237 } else {
01238 ret_val = tcl_get_weights(interp, app, sel1, objv[4], weight);
01239 }
01240 if (ret_val < 0) {
01241 Tcl_AppendResult(interp, "measure rmsd: ", measure_error(ret_val), NULL);
01242 delete [] weight;
01243 return TCL_ERROR;
01244 }
01245
01246
01247 float rmsd = 0;
01248 const float *x = sel1->coordinates(app->moleculeList);
01249 const float *y = sel2->coordinates(app->moleculeList);
01250 if (!x || !y) {
01251 delete [] weight;
01252 return TCL_ERROR;
01253 }
01254
01255 ret_val = measure_rmsd(sel1, sel2, sel1->selected, x, y, weight, &rmsd);
01256 delete [] weight;
01257 if (ret_val < 0) {
01258 Tcl_AppendResult(interp, "measure rmsd: ", measure_error(ret_val), NULL);
01259 return TCL_ERROR;
01260 }
01261 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rmsd));
01262
01263 return TCL_OK;
01264 }
01265
01266
01268
01269 static int vmd_measure_rmsd_qcp(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01270 if (argc !=3 && argc != 5) {
01271 Tcl_WrongNumArgs(interp, 2, objv-1,
01272 (char *)"<sel1> <sel2> [weight <weights>]");
01273 return TCL_ERROR;
01274 }
01275
01276 AtomSel *sel1 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
01277 AtomSel *sel2 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[2],NULL));
01278 if (!sel1 || !sel2) {
01279 Tcl_AppendResult(interp, "measure rmsd: no atom selection", NULL);
01280 return TCL_ERROR;
01281 }
01282
01283 if (sel1->selected != sel2->selected) {
01284 Tcl_AppendResult(interp, "measure rmsd: selections must have the same number of atoms", NULL);
01285 return TCL_ERROR;
01286 }
01287 if (!sel1->selected) {
01288 Tcl_AppendResult(interp, "measure rmsd: no atoms selected", NULL);
01289 return TCL_ERROR;
01290 }
01291 float *weight = new float[sel1->selected];
01292 {
01293 int ret_val;
01294 if (argc == 3) {
01295 ret_val = tcl_get_weights(interp, app, sel1, NULL, weight);
01296 } else {
01297 ret_val = tcl_get_weights(interp, app, sel1, objv[4], weight);
01298 }
01299 if (ret_val < 0) {
01300 Tcl_AppendResult(interp, "measure rmsd: ", measure_error(ret_val), NULL);
01301 delete [] weight;
01302 return TCL_ERROR;
01303 }
01304 }
01305
01306
01307 {
01308 float rmsd = 0;
01309 const float *x = sel1->coordinates(app->moleculeList);
01310 const float *y = sel2->coordinates(app->moleculeList);
01311 if (!x || !y) {
01312 delete [] weight;
01313 return TCL_ERROR;
01314 }
01315 int ret_val = measure_rmsd_qcp(app, sel1, sel2, sel1->selected, x, y, weight, &rmsd);
01316 delete [] weight;
01317 if (ret_val < 0) {
01318 Tcl_AppendResult(interp, "measure rmsd: ", measure_error(ret_val), NULL);
01319 return TCL_ERROR;
01320 }
01321 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rmsd));
01322 }
01323 return TCL_OK;
01324 }
01325
01326
01328
01329 static int vmd_measure_rmsdmat_qcp(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01330 int first = 0;
01331 int last = -1;
01332 int step = 1;
01333
01334 if (argc < 2 || argc > 9) {
01335 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<sel> [weight <weights>] [first <first>] [last <last>] [step <step>]");
01336 return TCL_ERROR;
01337 }
01338 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL)
01339 );
01340 if (!sel) {
01341 Tcl_AppendResult(interp, "measure rmsdmat_qcp: no atom selection", NULL);
01342 return TCL_ERROR;
01343 }
01344
01345 int i;
01346 for (i=2; i<argc; i+=2) {
01347 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
01348 if (!strupncmp(argvcur, "first", CMDLEN)) {
01349 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
01350 Tcl_AppendResult(interp, "measure rmsdmat_qcp: bad first frame value", NULL);
01351 return TCL_ERROR;
01352 }
01353 } else if (!strupncmp(argvcur, "last", CMDLEN)) {
01354 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
01355 Tcl_AppendResult(interp, "measure rmsdmat_qcp: bad last frame value", NULL);
01356 return TCL_ERROR;
01357 }
01358 } else if (!strupncmp(argvcur, "step", CMDLEN)) {
01359 if (Tcl_GetIntFromObj(interp, objv[i+1], &step) != TCL_OK) {
01360 Tcl_AppendResult(interp, "measure rmsdmat_qcp: bad frame step value", NULL);
01361 return TCL_ERROR;
01362 }
01363 } else {
01364 Tcl_AppendResult(interp, "measure rmsdmat_qcp: invalid syntax, no such keyword: ", argvcur, NULL);
01365 return TCL_ERROR;
01366 }
01367 }
01368
01369 float *weight = NULL;
01370 if (0) {
01371 weight = new float[sel->selected];
01372 int ret_val;
01373 if (argc == 2) {
01374 ret_val = tcl_get_weights(interp, app, sel, NULL, weight);
01375 } else {
01376 ret_val = tcl_get_weights(interp, app, sel, objv[3], weight);
01377 }
01378
01379 if (ret_val < 0) {
01380 Tcl_AppendResult(interp, "measure rmsdmat_qcp: ", measure_error(ret_val),
01381 NULL);
01382 delete [] weight;
01383 return TCL_ERROR;
01384 }
01385 }
01386
01387
01388 if (last < 0)
01389 last = app->molecule_numframes(sel->molid()) - 1;
01390 int framecount = (last - first + 1) / step;
01391 float *rmsdmat = (float *) calloc(1, framecount * framecount * sizeof(float));
01392
01393
01394 int ret_val = measure_rmsdmat_qcp(app, sel, app->moleculeList,
01395 sel->selected, weight,
01396 first, last, step, rmsdmat);
01397 delete [] weight;
01398
01399 if (ret_val < 0) {
01400 Tcl_AppendResult(interp, "measure rmsdmat_qcp: ", measure_error(ret_val), NULL);
01401 return TCL_ERROR;
01402 }
01403
01404 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
01405 long j;
01406 for (j=0; j<framecount; j++) {
01407 Tcl_Obj *rmsdlist = Tcl_NewListObj(0, NULL);
01408 for (i=0; i<framecount; i++) {
01409 Tcl_ListObjAppendElement(interp, rmsdlist,
01410 Tcl_NewDoubleObj(rmsdmat[j*framecount + i]));
01411 }
01412 Tcl_ListObjAppendElement(interp, tcl_result, rmsdlist);
01413 }
01414 Tcl_SetObjResult(interp, tcl_result);
01415
01416 free(rmsdmat);
01417
01418 return TCL_OK;
01419 }
01420
01421
01423
01424
01425
01426 static int vmd_measure_rmsdmat_qcp_ooc(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01427 int first = 0;
01428 int last = -1;
01429 int step = 1;
01430 int i;
01431 float *weight = NULL;
01432 int nfiles = 0;
01433 const char **trjfileset = NULL;
01434
01435 if (argc < 2) {
01436 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<sel> [weight <weights>] [first <first>] [last <last>] [step <step>] files [file1] [fileN]");
01437 return TCL_ERROR;
01438 }
01439 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL)
01440 );
01441 if (!sel) {
01442 Tcl_AppendResult(interp, "measure rmsdmat_qcp: no atom selection", NULL);
01443 return TCL_ERROR;
01444 }
01445
01446 for (i=2; i<argc; i+=2) {
01447 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
01448 if (!strupncmp(argvcur, "first", CMDLEN)) {
01449 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
01450 Tcl_AppendResult(interp, "measure rmsdmat_qcp_ooc: bad first frame value", NULL);
01451 return TCL_ERROR;
01452 }
01453 } else if (!strupncmp(argvcur, "last", CMDLEN)) {
01454 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
01455 Tcl_AppendResult(interp, "measure rmsdmat_qcp_ooc: bad last frame value", NULL);
01456 return TCL_ERROR;
01457 }
01458 } else if (!strupncmp(argvcur, "step", CMDLEN)) {
01459 if (Tcl_GetIntFromObj(interp, objv[i+1], &step) != TCL_OK) {
01460 Tcl_AppendResult(interp, "measure rmsdmat_qcp_ooc: bad frame step value", NULL);
01461 return TCL_ERROR;
01462 }
01463 } else if (!strupncmp(argvcur, "files", CMDLEN)) {
01464 int list_num;
01465 Tcl_Obj **list_data;
01466 if (Tcl_ListObjGetElements(interp, objv[i+1], &list_num, &list_data) != TCL_OK) {
01467 Tcl_AppendResult(interp, "measure rmsdmat_qcp_ooc: bad trajectory file list", NULL);
01468 return TCL_ERROR;
01469 }
01470
01471 int f;
01472 nfiles = list_num;
01473 trjfileset = (const char **) calloc(1, nfiles * sizeof(const char *));
01474 for (f=0; f<nfiles; f++) {
01475 trjfileset[f] = Tcl_GetStringFromObj(list_data[f], NULL);
01476 printf("File[%d] '%s'\n", f, trjfileset[f]);
01477 }
01478 } else {
01479 Tcl_AppendResult(interp, "measure rmsdmat_qcp_ooc: invalid syntax, no such keyword: ", argvcur, NULL);
01480 return TCL_ERROR;
01481 }
01482 }
01483
01484 #if 0
01485 if (0) {
01486 weight = new float[sel->selected];
01487 int ret_val;
01488 if (argc == 2) {
01489 ret_val = tcl_get_weights(interp, app, sel, NULL, weight);
01490 } else {
01491 ret_val = tcl_get_weights(interp, app, sel, objv[3], weight);
01492 }
01493
01494 if (ret_val < 0) {
01495 Tcl_AppendResult(interp, "measure rmsdmat_qcp: ", measure_error(ret_val),
01496 NULL);
01497 delete [] weight;
01498 return TCL_ERROR;
01499 }
01500 }
01501 #endif
01502
01503
01504 float *rmsdmat = NULL;
01505 int framecount = 0;
01506 int ret_val = measure_rmsdmat_qcp_ooc(app, sel, app->moleculeList,
01507 nfiles, trjfileset,
01508 sel->selected, weight,
01509 first, last, step,
01510 framecount, rmsdmat);
01511 delete [] weight;
01512
01513 if (ret_val < 0) {
01514 Tcl_AppendResult(interp, "measure rmsdmat_qcp_ooc: ", measure_error(ret_val), NULL);
01515 return TCL_ERROR;
01516 }
01517
01518 #if 0
01519 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
01520 long j;
01521 for (j=0; j<framecount; j++) {
01522 Tcl_Obj *rmsdlist = Tcl_NewListObj(0, NULL);
01523 for (i=0; i<framecount; i++) {
01524 Tcl_ListObjAppendElement(interp, rmsdlist,
01525 Tcl_NewDoubleObj(rmsdmat[j*framecount + i]));
01526 }
01527 Tcl_ListObjAppendElement(interp, tcl_result, rmsdlist);
01528 }
01529 Tcl_SetObjResult(interp, tcl_result);
01530 #endif
01531
01532 if (trjfileset != NULL)
01533 free(trjfileset);
01534
01535 if (rmsdmat != NULL)
01536 free(rmsdmat);
01537
01538 return TCL_OK;
01539 }
01540
01541
01542
01544
01545 static int vmd_measure_fit(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp)
01546 {
01547 AtomSel *sel1, *sel2;
01548 int *order = NULL;
01549 float *weight = NULL;
01550 int rc;
01551
01552 if (argc != 3 && argc != 5
01553 && argc != 7) {
01554 Tcl_WrongNumArgs(interp, 2, objv-1,
01555 (char *)"<sel1> <sel2> [weight <weights>] [order <index list>]");
01556 return TCL_ERROR;
01557 } else if (argc == 5
01558 && strcmp("weight", Tcl_GetStringFromObj(objv[3], NULL))
01559 && strcmp("order", Tcl_GetStringFromObj(objv[3], NULL))) {
01560 Tcl_WrongNumArgs(interp, 2, objv-1,
01561 (char *)"<sel1> <sel2> [weight <weights>] [order <index list>]");
01562 return TCL_ERROR;
01563 } else if (argc == 7 &&
01564 (strcmp("weight", Tcl_GetStringFromObj(objv[3], NULL)) ||
01565 strcmp("order", Tcl_GetStringFromObj(objv[5], NULL)))) {
01566 Tcl_WrongNumArgs(interp, 2, objv-1,
01567 (char *)"<sel1> <sel2> [weight <weights>] [order <index list>]");
01568 return TCL_ERROR;
01569 }
01570
01571
01572 sel1 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
01573 sel2 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[2],NULL));
01574
01575 if (!sel1 || !sel2) {
01576 Tcl_AppendResult(interp, "measure fit: no atom selection", NULL);
01577 return TCL_ERROR;
01578 }
01579
01580 int num = sel1->selected;
01581 if (!num) {
01582 Tcl_AppendResult(interp, "measure fit: no atoms selected", NULL);
01583 return TCL_ERROR;
01584 }
01585 if (num != sel2->selected) {
01586 Tcl_AppendResult(interp, "measure fit: selections must have the same number of atoms", NULL);
01587 return TCL_ERROR;
01588 }
01589
01590
01591 weight = new float[num];
01592 if (argc > 3 && !strcmp("weight", Tcl_GetStringFromObj(objv[3], NULL))) {
01593
01594 rc = tcl_get_weights(interp, app, sel1, objv[4], weight);
01595 } else {
01596
01597 rc = tcl_get_weights(interp, app, sel1, NULL, weight);
01598 }
01599 if (rc < 0) {
01600 Tcl_AppendResult(interp, "measure fit: ", measure_error(rc), NULL);
01601 delete [] weight;
01602 return TCL_ERROR;
01603 }
01604
01605
01606 int orderparam = 0;
01607 if (argc == 5 && !strcmp("order", Tcl_GetStringFromObj(objv[3], NULL))) {
01608 orderparam = 4;
01609 } else if (argc == 7 && !strcmp("order", Tcl_GetStringFromObj(objv[5], NULL))) {
01610 orderparam = 6;
01611 }
01612
01613 if (orderparam != 0) {
01614
01615 order = new int[num];
01616 rc = tcl_get_orders(interp, num, objv[orderparam], order);
01617 if (rc < 0) {
01618 Tcl_AppendResult(interp, "measure fit: ", measure_error(rc), NULL);
01619 delete [] order;
01620 return TCL_ERROR;
01621 }
01622 }
01623
01624
01625 Matrix4 T;
01626 const float *x = sel1->coordinates(app->moleculeList);
01627 const float *y = sel2->coordinates(app->moleculeList);
01628
01629 int ret_val = MEASURE_ERR_NOMOLECULE;
01630 if (x && y)
01631 ret_val = measure_fit(sel1, sel2, x, y, weight, order, &T);
01632
01633 delete [] weight;
01634
01635 if (order != NULL)
01636 delete [] order;
01637
01638 if (ret_val < 0) {
01639 Tcl_AppendResult(interp, "measure fit: ", measure_error(ret_val), NULL);
01640 return TCL_ERROR;
01641 }
01642
01643
01644 tcl_append_matrix(interp, T.mat);
01645 return TCL_OK;
01646 }
01647
01649
01650 static int vmd_measure_inverse(int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01651
01652 if (argc != 2) {
01653 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<matrix>");
01654 return TCL_ERROR;
01655 }
01656
01657 Matrix4 inv;
01658 if (tcl_get_matrix("measure inverse: ",interp,objv[1],inv.mat) != TCL_OK) {
01659 return TCL_ERROR;
01660 }
01661 if (inv.inverse()) {
01662 Tcl_AppendResult(interp, "Singular Matrix; inverse not computed", NULL);
01663 return TCL_ERROR;
01664 }
01665 tcl_append_matrix(interp, inv.mat);
01666 return TCL_OK;
01667 }
01668
01669
01670 static int vmd_measure_contacts(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01671
01672
01673 if (argc != 3 && argc != 4) {
01674 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<cutoff> <sel1> [<sel2>]");
01675 return TCL_ERROR;
01676 }
01677 AtomSel *sel1 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[2],NULL));
01678 if (!sel1) {
01679 Tcl_AppendResult(interp, "measure contacts: no atom selection", NULL);
01680 return TCL_ERROR;
01681 }
01682 AtomSel *sel2 = NULL;
01683 if (argc == 4) {
01684 sel2 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[3],NULL));
01685 if (!sel2) {
01686 Tcl_AppendResult(interp, "measure contacts: no atom selection", NULL);
01687 return TCL_ERROR;
01688 }
01689 }
01690 if (!sel2) sel2 = sel1;
01691
01692 double cutoff;
01693 if (Tcl_GetDoubleFromObj(interp, objv[1], &cutoff) != TCL_OK)
01694 return TCL_ERROR;
01695
01696 const float *pos1 = sel1->coordinates(app->moleculeList);
01697 const float *pos2 = sel2->coordinates(app->moleculeList);
01698 if (!pos1 || !pos2) {
01699 Tcl_AppendResult(interp, "measure contacts: error, molecule contains no coordinates", NULL);
01700 return TCL_ERROR;
01701 }
01702 Molecule *mol1 = app->moleculeList->mol_from_id(sel1->molid());
01703 Molecule *mol2 = app->moleculeList->mol_from_id(sel2->molid());
01704
01705 GridSearchPair *pairlist = vmd_gridsearch3(pos1, sel1->num_atoms, sel1->on, pos2, sel2->num_atoms, sel2->on, (float) cutoff, -1, (sel1->num_atoms + sel2->num_atoms) * 27L);
01706 GridSearchPair *p, *tmp;
01707 Tcl_Obj *list1 = Tcl_NewListObj(0, NULL);
01708 Tcl_Obj *list2 = Tcl_NewListObj(0, NULL);
01709 for (p=pairlist; p != NULL; p=tmp) {
01710
01711 MolAtom *a1 = mol1->atom(p->ind1);
01712 if (mol1 != mol2 || !a1->bonded(p->ind2)) {
01713 Tcl_ListObjAppendElement(interp, list1, Tcl_NewIntObj(p->ind1));
01714 Tcl_ListObjAppendElement(interp, list2, Tcl_NewIntObj(p->ind2));
01715 }
01716 tmp = p->next;
01717 free(p);
01718 }
01719 Tcl_Obj *result = Tcl_NewListObj(0, NULL);
01720 Tcl_ListObjAppendElement(interp, result, list1);
01721 Tcl_ListObjAppendElement(interp, result, list2);
01722 Tcl_SetObjResult(interp, result);
01723 return TCL_OK;
01724 }
01725
01726
01727
01728
01729 static int vmd_measure_gofr(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01730 int i;
01731
01732 double rmax=10.0;
01733 double delta=0.1;
01734 int usepbc=0;
01735 int selupdate=0;
01736 int first=-1, last=-1, step=1;
01737 int rc;
01738
01739
01740 const char *argerrmsg = "<sel1> <sel2> [delta <value>] [rmax <value>] [usepbc <bool>] [selupdate <bool>] [first <first>] [last <last>] [step <step>]";
01741
01742
01743 if ((argc < 3) || (argc > 17) || (argc % 2 == 0) ) {
01744 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)argerrmsg);
01745 return TCL_ERROR;
01746 }
01747
01748
01749 AtomSel *sel1 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1], NULL));
01750 if (!sel1) {
01751 Tcl_AppendResult(interp, "measure gofr: invalid first atom selection", NULL);
01752 return TCL_ERROR;
01753 }
01754
01755 AtomSel *sel2 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[2], NULL));
01756 if (!sel2) {
01757 Tcl_AppendResult(interp, "measure gofr: invalid second atom selection", NULL);
01758 return TCL_ERROR;
01759 }
01760
01761
01762 for (i=3; i<argc; i+=2) {
01763 const char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01764 if (i==(argc-1)) {
01765 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)argerrmsg);
01766 return TCL_ERROR;
01767 }
01768 if (!strcmp(opt, "delta")) {
01769 if (Tcl_GetDoubleFromObj(interp, objv[i+1], &delta) != TCL_OK)
01770 return TCL_ERROR;
01771 if (delta <= 0.0) {
01772 Tcl_AppendResult(interp, "measure gofr: invalid 'delta' value", NULL);
01773 return TCL_ERROR;
01774 }
01775 } else if (!strcmp(opt, "rmax")) {
01776 if (Tcl_GetDoubleFromObj(interp, objv[i+1], &rmax) != TCL_OK)
01777 return TCL_ERROR;
01778 if (rmax <= 0.0) {
01779 Tcl_AppendResult(interp, "measure gofr: invalid 'rmax' value", NULL);
01780 return TCL_ERROR;
01781 }
01782 } else if (!strcmp(opt, "usepbc")) {
01783 if (Tcl_GetBooleanFromObj(interp, objv[i+1], &usepbc) != TCL_OK)
01784 return TCL_ERROR;
01785 } else if (!strcmp(opt, "selupdate")) {
01786 if (Tcl_GetBooleanFromObj(interp, objv[i+1], &selupdate) != TCL_OK)
01787 return TCL_ERROR;
01788 } else if (!strcmp(opt, "first")) {
01789 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK)
01790 return TCL_ERROR;
01791 } else if (!strcmp(opt, "last")) {
01792 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK)
01793 return TCL_ERROR;
01794 } else if (!strcmp(opt, "step")) {
01795 if (Tcl_GetIntFromObj(interp, objv[i+1], &step) != TCL_OK)
01796 return TCL_ERROR;
01797 } else {
01798 Tcl_AppendResult(interp, "unknown keyword '", opt, "'. usage: measure gofr ", argerrmsg, NULL);
01799 return TCL_ERROR;
01800 }
01801 }
01802
01803
01804 int count_h = (int)(rmax / delta + 1.0);
01805 double *gofr = new double[count_h];
01806 double *numint = new double[count_h];
01807 double *histog = new double[count_h];
01808 int *framecntr = new int[3];
01809
01810
01811 rc = measure_gofr(sel1, sel2, app->moleculeList,
01812 count_h, gofr, numint, histog,
01813 (float) delta,
01814 first, last, step, framecntr,
01815 usepbc, selupdate);
01816
01817
01818 if (rc != MEASURE_NOERR) {
01819 Tcl_AppendResult(interp, "measure gofr: error during g(r) calculation.", NULL);
01820 return TCL_ERROR;
01821 }
01822
01823
01824
01825 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
01826 Tcl_Obj *tcl_rlist = Tcl_NewListObj(0, NULL);
01827 Tcl_Obj *tcl_gofr = Tcl_NewListObj(0, NULL);
01828 Tcl_Obj *tcl_numint = Tcl_NewListObj(0, NULL);
01829 Tcl_Obj *tcl_histog = Tcl_NewListObj(0, NULL);
01830 Tcl_Obj *tcl_frames = Tcl_NewListObj(0, NULL);
01831
01832
01833 for (i=0; i<count_h; i++) {
01834 Tcl_ListObjAppendElement(interp, tcl_rlist, Tcl_NewDoubleObj(delta * ((double)i + 0.5)));
01835 Tcl_ListObjAppendElement(interp, tcl_gofr, Tcl_NewDoubleObj(gofr[i]));
01836 Tcl_ListObjAppendElement(interp, tcl_numint, Tcl_NewDoubleObj(numint[i]));
01837 Tcl_ListObjAppendElement(interp, tcl_histog, Tcl_NewDoubleObj(histog[i]));
01838 }
01839
01840
01841
01842 Tcl_ListObjAppendElement(interp, tcl_frames, Tcl_NewIntObj(framecntr[0]));
01843 Tcl_ListObjAppendElement(interp, tcl_frames, Tcl_NewIntObj(framecntr[1]));
01844 Tcl_ListObjAppendElement(interp, tcl_frames, Tcl_NewIntObj(framecntr[2]));
01845
01846
01847 Tcl_ListObjAppendElement(interp, tcl_result, tcl_rlist);
01848 Tcl_ListObjAppendElement(interp, tcl_result, tcl_gofr);
01849 Tcl_ListObjAppendElement(interp, tcl_result, tcl_numint);
01850 Tcl_ListObjAppendElement(interp, tcl_result, tcl_histog);
01851 Tcl_ListObjAppendElement(interp, tcl_result, tcl_frames);
01852 Tcl_SetObjResult(interp, tcl_result);
01853
01854 delete [] gofr;
01855 delete [] numint;
01856 delete [] histog;
01857 delete [] framecntr;
01858 return TCL_OK;
01859 }
01860
01861
01862
01863
01864 static int vmd_measure_rdf(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01865 int i;
01866
01867 double rmax=10.0;
01868 double delta=0.1;
01869 int usepbc=0;
01870 int selupdate=0;
01871 int first=-1, last=-1, step=1;
01872 int rc;
01873
01874
01875 const char *argerrmsg = "<sel1> <sel2> [delta <value>] [rmax <value>] [usepbc <bool>] [selupdate <bool>] [first <first>] [last <last>] [step <step>]";
01876
01877
01878 if ((argc < 3) || (argc > 17) || (argc % 2 == 0) ) {
01879 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)argerrmsg);
01880 return TCL_ERROR;
01881 }
01882
01883
01884 AtomSel *sel1 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1], NULL));
01885 if (!sel1) {
01886 Tcl_AppendResult(interp, "measure rdf: invalid first atom selection", NULL);
01887 return TCL_ERROR;
01888 }
01889
01890 AtomSel *sel2 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[2], NULL));
01891 if (!sel2) {
01892 Tcl_AppendResult(interp, "measure rdf: invalid second atom selection", NULL);
01893 return TCL_ERROR;
01894 }
01895
01896
01897 for (i=3; i<argc; i+=2) {
01898 const char *opt = Tcl_GetStringFromObj(objv[i], NULL);
01899 if (i==(argc-1)) {
01900 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)argerrmsg);
01901 return TCL_ERROR;
01902 }
01903 if (!strcmp(opt, "delta")) {
01904 if (Tcl_GetDoubleFromObj(interp, objv[i+1], &delta) != TCL_OK)
01905 return TCL_ERROR;
01906 if (delta <= 0.0) {
01907 Tcl_AppendResult(interp, "measure rdf: invalid 'delta' value", NULL);
01908 return TCL_ERROR;
01909 }
01910 } else if (!strcmp(opt, "rmax")) {
01911 if (Tcl_GetDoubleFromObj(interp, objv[i+1], &rmax) != TCL_OK)
01912 return TCL_ERROR;
01913 if (rmax <= 0.0) {
01914 Tcl_AppendResult(interp, "measure rdf: invalid 'rmax' value", NULL);
01915 return TCL_ERROR;
01916 }
01917 } else if (!strcmp(opt, "usepbc")) {
01918 if (Tcl_GetBooleanFromObj(interp, objv[i+1], &usepbc) != TCL_OK)
01919 return TCL_ERROR;
01920 } else if (!strcmp(opt, "selupdate")) {
01921 if (Tcl_GetBooleanFromObj(interp, objv[i+1], &selupdate) != TCL_OK)
01922 return TCL_ERROR;
01923 } else if (!strcmp(opt, "first")) {
01924 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK)
01925 return TCL_ERROR;
01926 } else if (!strcmp(opt, "last")) {
01927 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK)
01928 return TCL_ERROR;
01929 } else if (!strcmp(opt, "step")) {
01930 if (Tcl_GetIntFromObj(interp, objv[i+1], &step) != TCL_OK)
01931 return TCL_ERROR;
01932 } else {
01933 Tcl_AppendResult(interp, "unknown keyword '", opt, "'. usage: measure rdf ", argerrmsg, NULL);
01934 return TCL_ERROR;
01935 }
01936 }
01937
01938
01939 int count_h = (int)(rmax / delta + 1.0);
01940 double *gofr = new double[count_h];
01941 double *numint = new double[count_h];
01942 double *histog = new double[count_h];
01943 int *framecntr = new int[3];
01944
01945
01946 rc = measure_rdf(app, sel1, sel2, app->moleculeList,
01947 count_h, gofr, numint, histog,
01948 (float) delta,
01949 first, last, step, framecntr,
01950 usepbc, selupdate);
01951
01952
01953 if (rc != MEASURE_NOERR) {
01954 Tcl_AppendResult(interp, "measure rdf: error during rdf calculation.", NULL);
01955 return TCL_ERROR;
01956 }
01957
01958
01959
01960 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
01961 Tcl_Obj *tcl_rlist = Tcl_NewListObj(0, NULL);
01962 Tcl_Obj *tcl_gofr = Tcl_NewListObj(0, NULL);
01963 Tcl_Obj *tcl_numint = Tcl_NewListObj(0, NULL);
01964 Tcl_Obj *tcl_histog = Tcl_NewListObj(0, NULL);
01965 Tcl_Obj *tcl_frames = Tcl_NewListObj(0, NULL);
01966
01967
01968 for (i=0; i<count_h; i++) {
01969 Tcl_ListObjAppendElement(interp, tcl_rlist, Tcl_NewDoubleObj(delta * ((double)i + 0.5)));
01970 Tcl_ListObjAppendElement(interp, tcl_gofr, Tcl_NewDoubleObj(gofr[i]));
01971 Tcl_ListObjAppendElement(interp, tcl_numint, Tcl_NewDoubleObj(numint[i]));
01972 Tcl_ListObjAppendElement(interp, tcl_histog, Tcl_NewDoubleObj(histog[i]));
01973 }
01974
01975
01976
01977 Tcl_ListObjAppendElement(interp, tcl_frames, Tcl_NewIntObj(framecntr[0]));
01978 Tcl_ListObjAppendElement(interp, tcl_frames, Tcl_NewIntObj(framecntr[1]));
01979 Tcl_ListObjAppendElement(interp, tcl_frames, Tcl_NewIntObj(framecntr[2]));
01980
01981
01982 Tcl_ListObjAppendElement(interp, tcl_result, tcl_rlist);
01983 Tcl_ListObjAppendElement(interp, tcl_result, tcl_gofr);
01984 Tcl_ListObjAppendElement(interp, tcl_result, tcl_numint);
01985 Tcl_ListObjAppendElement(interp, tcl_result, tcl_histog);
01986 Tcl_ListObjAppendElement(interp, tcl_result, tcl_frames);
01987 Tcl_SetObjResult(interp, tcl_result);
01988
01989 delete [] gofr;
01990 delete [] numint;
01991 delete [] histog;
01992 delete [] framecntr;
01993 return TCL_OK;
01994 }
01995
01996
01998 static int vmd_measure_cluster(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
01999 int i,j;
02000
02001 int algorithm=0;
02002 int likeness=MEASURE_DIST_FITRMSD;
02003 int numcluster=5;
02004 double cutoff=1.0;
02005 float *weights=NULL;
02006 int selupdate=0;
02007 int first=0, last=-1, step=1;
02008 int rc;
02009
02010
02011 const char *argerrmsg = "<sel> [num <#clusters>] [distfunc <flag>] "
02012 "[cutoff <cutoff>] [first <first>] [last <last>] [step <step>] "
02013 "[selupdate <bool>] [weight <weights>]";
02014
02015
02016 if ((argc < 2) || (argc > 19) || ((argc-1) % 2 == 0) ) {
02017 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)argerrmsg);
02018 return TCL_ERROR;
02019 }
02020
02021
02022 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1], NULL));
02023 if (!sel) {
02024 Tcl_AppendResult(interp, "measure cluster: invalid atom selection", NULL);
02025 return TCL_ERROR;
02026 }
02027 if (!app->molecule_valid_id(sel->molid())) return MEASURE_ERR_NOMOLECULE;
02028
02029
02030 for (i=2; i<argc; i+=2) {
02031 const char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02032 if (i==(argc-1)) {
02033 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)argerrmsg);
02034 return TCL_ERROR;
02035 }
02036 if (!strcmp(opt, "num")) {
02037 if (Tcl_GetIntFromObj(interp, objv[i+1], &numcluster) != TCL_OK)
02038 return TCL_ERROR;
02039 if (numcluster < 1) {
02040 Tcl_AppendResult(interp, "measure cluster: invalid 'num' value (cannot be smaller than 1)", NULL);
02041 return TCL_ERROR;
02042 }
02043 } else if (!strcmp(opt, "cutoff")) {
02044 if (Tcl_GetDoubleFromObj(interp, objv[i+1], &cutoff) != TCL_OK)
02045 return TCL_ERROR;
02046 if (cutoff <= 0.0) {
02047 Tcl_AppendResult(interp, "measure cluster: invalid 'cutoff' value (should be larger than 0.0)", NULL);
02048 return TCL_ERROR;
02049 }
02050 } else if (!strcmp(opt, "distfunc")) {
02051 char *argstr = Tcl_GetStringFromObj(objv[i+1], NULL);
02052 if (!strcmp(argstr,"rmsd")) {
02053 likeness = MEASURE_DIST_RMSD;
02054 } else if (!strcmp(argstr,"fitrmsd")) {
02055 likeness = MEASURE_DIST_FITRMSD;
02056 } else if (!strcmp(argstr,"rgyrd")) {
02057 likeness = MEASURE_DIST_RGYRD;
02058 } else {
02059 Tcl_AppendResult(interp, "measure cluster: unknown distance function (supported are 'rmsd', 'rgyrd' and 'fitrmsd')", NULL);
02060 return TCL_ERROR;
02061 }
02062 } else if (!strcmp(opt, "selupdate")) {
02063 if (Tcl_GetBooleanFromObj(interp, objv[i+1], &selupdate) != TCL_OK)
02064 return TCL_ERROR;
02065 } else if (!strcmp(opt, "weight")) {
02066
02067
02068
02069
02070 const char *weight_string = Tcl_GetStringFromObj(objv[i+1], NULL);
02071 weights = new float[sel->num_atoms];
02072
02073 if (!weight_string || !strcmp(weight_string, "none")) {
02074 for (j=0; j<sel->num_atoms; j++) weights[j]=1.0f;
02075 } else {
02076
02077 SymbolTable *atomSelParser = app->atomSelParser;
02078
02079
02080 atomsel_ctxt context(atomSelParser,
02081 app->moleculeList->mol_from_id(sel->molid()),
02082 sel->which_frame, NULL);
02083
02084 int fctn = atomSelParser->find_attribute(weight_string);
02085 if (fctn >= 0) {
02086
02087
02088
02089 if (atomSelParser->fctns.data(fctn)->returns_a != SymbolTableElement::IS_FLOAT) {
02090 Tcl_AppendResult(interp, "weight attribute must have floating point values", NULL);
02091 delete [] weights;
02092 return MEASURE_ERR_BADWEIGHTPARM;
02093 }
02094
02095 double *tmp_data = new double[sel->num_atoms];
02096 int *all_on = new int[sel->num_atoms];
02097 for (j=0; j<sel->num_atoms; j++) all_on[j]=1;
02098
02099 atomSelParser->fctns.data(fctn)->keyword_double(
02100 &context, sel->num_atoms, tmp_data, all_on);
02101
02102 for (j=0; j<sel->num_atoms; j++) weights[j] = (float)tmp_data[j];
02103
02104
02105 delete [] tmp_data;
02106 delete [] all_on;
02107 }
02108 }
02109 } else if (!strcmp(opt, "first")) {
02110 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK)
02111 return TCL_ERROR;
02112 } else if (!strcmp(opt, "last")) {
02113 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK)
02114 return TCL_ERROR;
02115 } else if (!strcmp(opt, "step")) {
02116 if (Tcl_GetIntFromObj(interp, objv[i+1], &step) != TCL_OK)
02117 return TCL_ERROR;
02118 } else {
02119 Tcl_AppendResult(interp, "unknown keyword '", opt, "'. usage: measure cluster ", argerrmsg, NULL);
02120 return TCL_ERROR;
02121 }
02122 }
02123
02124
02125 if (!weights) {
02126 weights = new float[sel->num_atoms];
02127 for (j=0; j<sel->num_atoms; j++) weights[j]=1.0f;
02128 }
02129
02130
02131
02132
02133
02134 int *clustersize = new int [numcluster+1];
02135 int **clusterlist = new int *[numcluster+1];
02136
02137
02138 rc = measure_cluster(sel, app->moleculeList, numcluster, algorithm, likeness, cutoff,
02139 clustersize, clusterlist, first, last, step, selupdate, weights);
02140
02141 if (weights) delete [] weights;
02142
02143
02144 if (rc != MEASURE_NOERR) {
02145 Tcl_AppendResult(interp, "measure cluster: error during cluster analysis calculation.", NULL);
02146 return TCL_ERROR;
02147 }
02148
02149
02150
02151 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
02152
02153 for (i=0; i <= numcluster; ++i) {
02154 int j;
02155 Tcl_Obj *tcl_clist = Tcl_NewListObj(0, NULL);
02156 for (j=0; j < clustersize[i]; ++j) {
02157 Tcl_ListObjAppendElement(interp, tcl_clist, Tcl_NewIntObj(clusterlist[i][j]));
02158 }
02159 Tcl_ListObjAppendElement(interp, tcl_result, tcl_clist);
02160 }
02161 Tcl_SetObjResult(interp, tcl_result);
02162
02163
02164 for (i=0; i <= numcluster; ++i)
02165 delete[] clusterlist[i];
02166
02167 delete[] clusterlist;
02168 delete[] clustersize;
02169
02170 return TCL_OK;
02171 }
02172
02174 static int vmd_measure_clustsize(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02175 int i;
02176
02177 double cutoff=3.0;
02178 char *storesize=NULL;
02179 char *storenum=NULL;
02180 int usepbc=0;
02181 int minsize=2;
02182 int numshared=1;
02183 int rc;
02184
02185
02186 const char *argerrmsg = "<sel> [cutoff <float>] [minsize <num>] [numshared <num>] "
02187 "[usepbc <bool>] [storesize <fieldname>] [storenum <fieldname>]";
02188
02189
02190 if ((argc < 2) || (argc > 13) || ((argc-1) % 2 == 0) ) {
02191 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)argerrmsg);
02192 return TCL_ERROR;
02193 }
02194
02195
02196 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1], NULL));
02197 if (!sel) {
02198 Tcl_AppendResult(interp, "measure clustsize: invalid atom selection", NULL);
02199 return TCL_ERROR;
02200 }
02201 if (!app->molecule_valid_id(sel->molid())) return MEASURE_ERR_NOMOLECULE;
02202
02203
02204 for (i=2; i<argc; i+=2) {
02205 const char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02206 if (i==(argc-1)) {
02207 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)argerrmsg);
02208 return TCL_ERROR;
02209 } else if (!strcmp(opt, "cutoff")) {
02210 if (Tcl_GetDoubleFromObj(interp, objv[i+1], &cutoff) != TCL_OK)
02211 return TCL_ERROR;
02212 if (cutoff <= 0.0) {
02213 Tcl_AppendResult(interp, "measure clustsize: invalid 'cutoff' value", NULL);
02214 return TCL_ERROR;
02215 }
02216 } else if (!strcmp(opt, "minsize")) {
02217 if (Tcl_GetIntFromObj(interp, objv[i+1], &minsize) != TCL_OK)
02218 return TCL_ERROR;
02219 if (minsize < 2) {
02220 Tcl_AppendResult(interp, "measure clustsize: invalid 'minsize' value", NULL);
02221 return TCL_ERROR;
02222 }
02223 } else if (!strcmp(opt, "numshared")) {
02224 if (Tcl_GetIntFromObj(interp, objv[i+1], &numshared) != TCL_OK)
02225 return TCL_ERROR;
02226 if (numshared < 0) {
02227 Tcl_AppendResult(interp, "measure clustsize: invalid 'numshared' value", NULL);
02228 return TCL_ERROR;
02229 }
02230 } else if (!strcmp(opt, "usepbc")) {
02231 if (Tcl_GetBooleanFromObj(interp, objv[i+1], &usepbc) != TCL_OK)
02232 return TCL_ERROR;
02233 } else if (!strcmp(opt, "storenum")) {
02234 storenum = Tcl_GetStringFromObj(objv[i+1], NULL);
02235 } else if (!strcmp(opt, "storesize")) {
02236 storesize = Tcl_GetStringFromObj(objv[i+1], NULL);
02237 } else {
02238 Tcl_AppendResult(interp, "unknown keyword '", opt, "'. usage: measure clustsize ", argerrmsg, NULL);
02239 return TCL_ERROR;
02240 }
02241 }
02242
02243 if (usepbc) {
02244 Tcl_AppendResult(interp, "measure clustsize: does not support periodic boundaries yet.", NULL);
02245 return TCL_ERROR;
02246 }
02247
02248
02249
02250
02251 int num_selected=sel->selected;
02252 int *clustersize = new int[num_selected];
02253 int *clusternum= new int [num_selected];
02254 int *clusteridx= new int [num_selected];
02255 for (i=0; i < num_selected; i++) {
02256 clustersize[i] = 0;
02257 clusternum[i] = -1;
02258 clusteridx[i] = -1;
02259 }
02260
02261
02262 rc = measure_clustsize(sel, app->moleculeList, cutoff,
02263 clustersize, clusternum, clusteridx,
02264 minsize, numshared, usepbc);
02265
02266
02267 if (rc != MEASURE_NOERR) {
02268 Tcl_AppendResult(interp, "measure clustsize: error during cluster size analysis calculation.", NULL);
02269 return TCL_ERROR;
02270 }
02271
02272
02273 if (storenum || storesize) {
02274
02275 SymbolTable *atomSelParser = app->atomSelParser;
02276 atomsel_ctxt context(atomSelParser,
02277 app->moleculeList->mol_from_id(sel->molid()),
02278 sel->which_frame, NULL);
02279
02280
02281 if (storenum) {
02282 int fctn = atomSelParser->find_attribute(storenum);
02283 if (fctn >= 0) {
02284 if (atomSelParser->fctns.data(fctn)->returns_a == SymbolTableElement::IS_FLOAT) {
02285 double *tmp_data = new double[sel->num_atoms];
02286 int j=0;
02287 for (int i=sel->firstsel; i<=sel->lastsel; i++) {
02288 if (sel->on[i])
02289 tmp_data[i] = (double) clusternum[j++];
02290 }
02291 atomSelParser->fctns.data(fctn)->set_keyword_double(&context,
02292 sel->num_atoms,
02293 tmp_data, sel->on);
02294 delete[] tmp_data;
02295
02296 } else if (atomSelParser->fctns.data(fctn)->returns_a == SymbolTableElement::IS_INT) {
02297 int *tmp_data = new int[sel->num_atoms];
02298 int j=0;
02299 for (int i=sel->firstsel; i<=sel->lastsel; i++) {
02300 if (sel->on[i])
02301 tmp_data[i] = clusternum[j++];
02302 }
02303 atomSelParser->fctns.data(fctn)->set_keyword_int(&context,
02304 sel->num_atoms,
02305 tmp_data, sel->on);
02306 delete[] tmp_data;
02307 } else {
02308 Tcl_AppendResult(interp, "measure clustsize: storenum field must accept numbers", NULL);
02309 return TCL_ERROR;
02310 }
02311 } else {
02312 Tcl_AppendResult(interp, "measure clustsize: invalid field name for storenum", NULL);
02313 return TCL_ERROR;
02314 }
02315 }
02316
02317
02318 if (storesize) {
02319 int fctn = atomSelParser->find_attribute(storesize);
02320 if (fctn >= 0) {
02321 if (atomSelParser->fctns.data(fctn)->returns_a == SymbolTableElement::IS_FLOAT) {
02322 double *tmp_data = new double[sel->num_atoms];
02323 int j=0;
02324 for (int i=sel->firstsel; i<=sel->lastsel; i++) {
02325 if (sel->on[i])
02326 tmp_data[i] = (double) clustersize[j++];
02327 }
02328 atomSelParser->fctns.data(fctn)->set_keyword_double(&context,
02329 sel->num_atoms,
02330 tmp_data, sel->on);
02331 delete[] tmp_data;
02332
02333 } else if (atomSelParser->fctns.data(fctn)->returns_a == SymbolTableElement::IS_INT) {
02334 int *tmp_data = new int[sel->num_atoms];
02335 int j=0;
02336 for (int i=sel->firstsel; i<=sel->lastsel; i++) {
02337 if (sel->on[i])
02338 tmp_data[i] = clustersize[j++];
02339 }
02340 atomSelParser->fctns.data(fctn)->set_keyword_int(&context,
02341 sel->num_atoms,
02342 tmp_data, sel->on);
02343 delete[] tmp_data;
02344 } else {
02345 Tcl_AppendResult(interp, "measure clustsize: storenum field must accept numbers", NULL);
02346 return TCL_ERROR;
02347 }
02348 } else {
02349 Tcl_AppendResult(interp, "measure clustsize: invalid field name for storesize", NULL);
02350 return TCL_ERROR;
02351 }
02352 }
02353 } else {
02354
02355
02356 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
02357
02358 Tcl_Obj *tcl_ilist = Tcl_NewListObj(0, NULL);
02359 Tcl_Obj *tcl_clist = Tcl_NewListObj(0, NULL);
02360 Tcl_Obj *tcl_nlist = Tcl_NewListObj(0, NULL);
02361 for (i=0; i<num_selected; i++) {
02362 Tcl_ListObjAppendElement(interp, tcl_ilist, Tcl_NewIntObj(clusteridx[i]));
02363 Tcl_ListObjAppendElement(interp, tcl_clist, Tcl_NewIntObj(clustersize[i]));
02364 Tcl_ListObjAppendElement(interp, tcl_nlist, Tcl_NewIntObj(clusternum[i]));
02365 }
02366 Tcl_ListObjAppendElement(interp, tcl_result, tcl_ilist);
02367 Tcl_ListObjAppendElement(interp, tcl_result, tcl_clist);
02368 Tcl_ListObjAppendElement(interp, tcl_result, tcl_nlist);
02369 Tcl_SetObjResult(interp, tcl_result);
02370 }
02371
02372 delete[] clustersize;
02373 delete[] clusternum;
02374 delete[] clusteridx;
02375
02376 return TCL_OK;
02377 }
02378
02379 static int vmd_measure_hbonds(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02380
02381
02382 if (argc != 4 && argc != 5) {
02383 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<cutoff> <angle> <selection1> [<selection2>]");
02384 return TCL_ERROR;
02385 }
02386 AtomSel *sel1 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[3],NULL));
02387 if (!sel1) {
02388 Tcl_AppendResult(interp, "measure hbonds: invalid first atom selection", NULL);
02389 return TCL_ERROR;
02390 }
02391
02392 AtomSel *sel2 = NULL;
02393 if (argc == 5) {
02394 sel2 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[4],NULL));
02395 if (!sel2) {
02396 Tcl_AppendResult(interp, "measure hbonds: invalid second atom selection", NULL);
02397 return TCL_ERROR;
02398 }
02399 }
02400 if (sel2 && sel2->molid() != sel1->molid()) {
02401 Tcl_AppendResult(interp, "measure hbonds: error, atom selections must come from same molecule.", NULL);
02402 return TCL_ERROR;
02403 }
02404 double cutoff;
02405 if (Tcl_GetDoubleFromObj(interp, objv[1], &cutoff) != TCL_OK)
02406 return TCL_ERROR;
02407
02408 double maxangle;
02409 if (Tcl_GetDoubleFromObj(interp, objv[2], &maxangle) != TCL_OK)
02410 return TCL_ERROR;
02411
02412 const float *pos = sel1->coordinates(app->moleculeList);
02413 if (!pos) {
02414 Tcl_AppendResult(interp, "measure bondsearch: error, molecule contains no coordinates", NULL);
02415 return TCL_ERROR;
02416 }
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431 Molecule *mol = app->moleculeList->mol_from_id(sel1->molid());
02432
02433 int *donlist, *hydlist, *acclist;
02434 int maxsize = 2 * sel1->num_atoms;
02435 donlist = new int[maxsize];
02436 hydlist = new int[maxsize];
02437 acclist = new int[maxsize];
02438 int rc = measure_hbonds(mol, sel1, sel2, cutoff, maxangle, donlist, hydlist, acclist, maxsize);
02439 if (rc > maxsize) {
02440 delete [] donlist;
02441 delete [] hydlist;
02442 delete [] acclist;
02443 maxsize = rc;
02444 donlist = new int[maxsize];
02445 hydlist = new int[maxsize];
02446 acclist = new int[maxsize];
02447 rc = measure_hbonds(mol, sel1, sel2, cutoff, maxangle, donlist, hydlist, acclist, maxsize);
02448 }
02449 if (rc < 0) {
02450 Tcl_AppendResult(interp, "measure hbonds: internal error to measure_hbonds", NULL);
02451 return TCL_ERROR;
02452 }
02453
02454 Tcl_Obj *newdonlist = Tcl_NewListObj(0, NULL);
02455 Tcl_Obj *newhydlist = Tcl_NewListObj(0, NULL);
02456 Tcl_Obj *newacclist = Tcl_NewListObj(0, NULL);
02457 for (int k = 0; k < rc; k++) {
02458 Tcl_ListObjAppendElement(interp, newdonlist, Tcl_NewIntObj(donlist[k]));
02459 Tcl_ListObjAppendElement(interp, newhydlist, Tcl_NewIntObj(hydlist[k]));
02460 Tcl_ListObjAppendElement(interp, newacclist, Tcl_NewIntObj(acclist[k]));
02461 }
02462 delete [] donlist;
02463 delete [] hydlist;
02464 delete [] acclist;
02465 Tcl_Obj *result = Tcl_NewListObj(0, NULL);
02466 Tcl_ListObjAppendElement(interp, result, newdonlist);
02467 Tcl_ListObjAppendElement(interp, result, newacclist);
02468 Tcl_ListObjAppendElement(interp, result, newhydlist);
02469 Tcl_SetObjResult(interp, result);
02470 return TCL_OK;
02471 }
02472
02473 static int vmd_measure_sasaperresidue(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02474
02475 int i;
02476
02477 if (argc < 3) {
02478 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<srad> <sel> [-restrict <restrictedsel>] [-samples <numsamples>]");
02479 return TCL_ERROR;
02480 }
02481
02482 Tcl_Obj *ptsvar = NULL;
02483 AtomSel *restrictsel = NULL;
02484 int nsamples = -1, rescount;
02485 int *sampleptr = NULL;
02486 for (i=3; i<argc-1; i+=2) {
02487 const char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02488 if (!strcmp(opt, "-points")) {
02489 ptsvar = objv[i+1];
02490 } else if (!strcmp(opt, "-restrict")) {
02491 restrictsel = tcl_commands_get_sel(interp,
02492 Tcl_GetStringFromObj(objv[i+1], NULL));
02493 if (!restrictsel) {
02494 Tcl_AppendResult(interp, "measure sasa: invalid restrict atom selection", NULL);
02495 return TCL_ERROR;
02496 }
02497 } else if (!strcmp(opt, "-samples")) {
02498 if (Tcl_GetIntFromObj(interp, objv[i+1], &nsamples) != TCL_OK)
02499 return TCL_ERROR;
02500 sampleptr = &nsamples;
02501 } else {
02502 Tcl_AppendResult(interp, "measure sasa per residue: unknown option '", opt, "'",
02503 NULL);
02504 return TCL_ERROR;
02505 }
02506 }
02507
02508 double srad;
02509 if (Tcl_GetDoubleFromObj(interp, objv[1], &srad) != TCL_OK)
02510 return TCL_ERROR;
02511 AtomSel *sel1 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[2],NULL));
02512 if (!sel1) {
02513 Tcl_AppendResult(interp, "measure sasa per residue: invalid first atom selection", NULL);
02514 return TCL_ERROR;
02515 }
02516
02517 const float *pos = sel1->coordinates(app->moleculeList);
02518 if (!pos) {
02519 Tcl_AppendResult(interp, "measure sasa per residue: error, molecule contains no coordinates", NULL);
02520 return TCL_ERROR;
02521 }
02522 Molecule *mol = app->moleculeList->mol_from_id(sel1->molid());
02523 const float *radius = mol->extraflt.data("radius");
02524
02525 ResizeArray<float> sasapts;
02526 float *sasavals;
02527 sasavals = new float[sel1->selected];
02528 int rc = measure_sasa_perresidue(sel1, pos, radius, (float) srad, sasavals, &sasapts,
02529 restrictsel, sampleptr,&rescount,app->moleculeList);
02530 if (rc < 0) {
02531 Tcl_AppendResult(interp, "measure: sasa per residue : ", measure_error(rc), NULL);
02532 delete [] sasavals;
02533 return TCL_ERROR;
02534 }
02535 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
02536 for (int i=0; i<rescount; i++) {
02537 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(sasavals[i]));
02538 }
02539 Tcl_SetObjResult(interp, tcl_result);
02540 if (ptsvar) {
02541
02542 Tcl_Obj *listobj = Tcl_NewListObj(0, NULL);
02543 i=0;
02544 while (i<sasapts.num()) {
02545 Tcl_Obj *elem = Tcl_NewListObj(0, NULL);
02546 Tcl_ListObjAppendElement(interp, elem, Tcl_NewDoubleObj(sasapts[i++]));
02547 Tcl_ListObjAppendElement(interp, elem, Tcl_NewDoubleObj(sasapts[i++]));
02548 Tcl_ListObjAppendElement(interp, elem, Tcl_NewDoubleObj(sasapts[i++]));
02549 Tcl_ListObjAppendElement(interp, listobj, elem);
02550 }
02551 Tcl_ObjSetVar2(interp, ptsvar, NULL, listobj, 0);
02552 }
02553 delete [] sasavals;
02554 return TCL_OK;
02555 }
02556
02557
02558 static int vmd_measure_sasa(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02559
02560 int i;
02561
02562 if (argc < 3) {
02563 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<srad> <sel> [-points <varname>] [-restrict <restrictedsel>] [-samples <numsamples>]");
02564 return TCL_ERROR;
02565 }
02566
02567 Tcl_Obj *ptsvar = NULL;
02568 AtomSel *restrictsel = NULL;
02569 int nsamples = -1;
02570 int *sampleptr = NULL;
02571 for (i=3; i<argc-1; i+=2) {
02572 const char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02573 if (!strcmp(opt, "-points")) {
02574 ptsvar = objv[i+1];
02575 } else if (!strcmp(opt, "-restrict")) {
02576 restrictsel = tcl_commands_get_sel(interp,
02577 Tcl_GetStringFromObj(objv[i+1], NULL));
02578 if (!restrictsel) {
02579 Tcl_AppendResult(interp, "measure sasa: invalid restrict atom selection", NULL);
02580 return TCL_ERROR;
02581 }
02582 } else if (!strcmp(opt, "-samples")) {
02583 if (Tcl_GetIntFromObj(interp, objv[i+1], &nsamples) != TCL_OK)
02584 return TCL_ERROR;
02585 sampleptr = &nsamples;
02586 } else {
02587 Tcl_AppendResult(interp, "measure sasa: unknown option '", opt, "'",
02588 NULL);
02589 return TCL_ERROR;
02590 }
02591 }
02592
02593 double srad;
02594 if (Tcl_GetDoubleFromObj(interp, objv[1], &srad) != TCL_OK)
02595 return TCL_ERROR;
02596 AtomSel *sel1 = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[2],NULL));
02597 if (!sel1) {
02598 Tcl_AppendResult(interp, "measure sasa: invalid first atom selection", NULL);
02599 return TCL_ERROR;
02600 }
02601
02602 const float *pos = sel1->coordinates(app->moleculeList);
02603 if (!pos) {
02604 Tcl_AppendResult(interp, "measure sasa: error, molecule contains no coordinates", NULL);
02605 return TCL_ERROR;
02606 }
02607 Molecule *mol = app->moleculeList->mol_from_id(sel1->molid());
02608 const float *radius = mol->extraflt.data("radius");
02609
02610 ResizeArray<float> sasapts;
02611 float sasa = 0;
02612 int rc = measure_sasa(sel1, pos, radius, (float) srad, &sasa, &sasapts,
02613 restrictsel, sampleptr);
02614 if (rc < 0) {
02615 Tcl_AppendResult(interp, "measure: sasa: ", measure_error(rc), NULL);
02616 return TCL_ERROR;
02617 }
02618 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(sasa));
02619 if (ptsvar) {
02620
02621 Tcl_Obj *listobj = Tcl_NewListObj(0, NULL);
02622 i=0;
02623 while (i<sasapts.num()) {
02624 Tcl_Obj *elem = Tcl_NewListObj(0, NULL);
02625 Tcl_ListObjAppendElement(interp, elem, Tcl_NewDoubleObj(sasapts[i++]));
02626 Tcl_ListObjAppendElement(interp, elem, Tcl_NewDoubleObj(sasapts[i++]));
02627 Tcl_ListObjAppendElement(interp, elem, Tcl_NewDoubleObj(sasapts[i++]));
02628 Tcl_ListObjAppendElement(interp, listobj, elem);
02629 }
02630 Tcl_ObjSetVar2(interp, ptsvar, NULL, listobj, 0);
02631 }
02632 return TCL_OK;
02633 }
02634
02635
02636 #if 1
02637
02638 static int vmd_measure_sasalist(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02639
02640 int i;
02641
02642 if (argc < 3) {
02643 Tcl_WrongNumArgs(interp, 2, objv-1, (char *)"<srad> <sel list> [-samples <numsamples>]");
02644 return TCL_ERROR;
02645 }
02646
02647
02648 int nsamples = -1;
02649 int *sampleptr = NULL;
02650 for (i=3; i<argc-1; i+=2) {
02651 const char *opt = Tcl_GetStringFromObj(objv[i], NULL);
02652
02653 if (!strcmp(opt, "-samples")) {
02654 if (Tcl_GetIntFromObj(interp, objv[i+1], &nsamples) != TCL_OK)
02655 return TCL_ERROR;
02656 sampleptr = &nsamples;
02657 } else {
02658 Tcl_AppendResult(interp, "measure sasa: unknown option '", opt, "'", NULL);
02659 return TCL_ERROR;
02660 }
02661 }
02662
02663 double srad;
02664 if (Tcl_GetDoubleFromObj(interp, objv[1], &srad) != TCL_OK)
02665 return TCL_ERROR;
02666
02667 int numsels;
02668 Tcl_Obj **sel_list;
02669 if (Tcl_ListObjGetElements(interp, objv[2], &numsels, &sel_list) != TCL_OK) {
02670 Tcl_AppendResult(interp, "measure sasalist: bad selection list", NULL);
02671 return TCL_ERROR;
02672 }
02673
02674 #if 0
02675 printf("measure sasalist: numsels %d\n", numsels);
02676 #endif
02677
02678 AtomSel **asels = (AtomSel **) calloc(1, numsels * sizeof(AtomSel *));
02679 float *sasalist = (float *) calloc(1, numsels * sizeof(float));
02680
02681 int s;
02682 for (s=0; s<numsels; s++) {
02683 asels[s] = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(sel_list[s], NULL));
02684 if (!asels[s]) {
02685 printf("measure sasalist: invalid selection %d\n", s);
02686 Tcl_AppendResult(interp, "measure sasalist: invalid atom selection list element", NULL);
02687 return TCL_ERROR;
02688 }
02689 }
02690
02691 int rc = measure_sasalist(app->moleculeList, (const AtomSel **) asels,
02692 numsels, (float) srad, sasalist, sampleptr);
02693 free(asels);
02694 if (rc < 0) {
02695 Tcl_AppendResult(interp, "measure: sasalist: ", measure_error(rc), NULL);
02696 return TCL_ERROR;
02697 }
02698
02699
02700 Tcl_Obj *listobj = Tcl_NewListObj(0, NULL);
02701 for (i=0; i<numsels; i++) {
02702 Tcl_ListObjAppendElement(interp, listobj, Tcl_NewDoubleObj(sasalist[i]));
02703 }
02704 Tcl_SetObjResult(interp, listobj);
02705 free(sasalist);
02706
02707 return TCL_OK;
02708 }
02709
02710 #endif
02711
02712
02713
02714
02715
02716 static int vmd_measure_energy(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02717
02718 if (argc<3) {
02719 Tcl_WrongNumArgs(interp, 2, objv-1,
02720 (char *) "bond|angle|dihed|imprp|vdw|elec {{<atomid1> ?<molid1>?} {<atomid2> ?<molid2>?}} ?molid <default molid>? [?frame <frame|all>? | ?first <first>? ?last <last>?]");
02721 return TCL_ERROR;
02722 }
02723
02724 int geomtype, reqatoms;
02725 char *geomname = Tcl_GetStringFromObj(objv[1],NULL);
02726 if (!strncmp(geomname, "bond", 4)) {
02727 reqatoms = 2; geomtype = MEASURE_BOND;
02728 } else if (!strncmp(geomname, "angl", 4)) {
02729 reqatoms = 3; geomtype = MEASURE_ANGLE;
02730 } else if (!strncmp(geomname, "dihe", 4)) {
02731 reqatoms = 4; geomtype = MEASURE_DIHED;
02732 } else if (!strncmp(geomname, "impr", 4)) {
02733 reqatoms = 4; geomtype = MEASURE_IMPRP;
02734 } else if (!strncmp(geomname, "vdw", 3)) {
02735 reqatoms = 2; geomtype = MEASURE_VDW;
02736 } else if (!strncmp(geomname, "elec", 4)) {
02737 reqatoms = 2; geomtype = MEASURE_ELECT;
02738 } else {
02739 Tcl_AppendResult(interp, " measure energy: bad syntax (must specify bond|angle|dihed|imprp|vdw|elec)", NULL);
02740 return TCL_ERROR;
02741 }
02742
02743 int molid[4];
02744 int atmid[4];
02745 int defmolid = -1;
02746 bool allframes = false;
02747 char errstring[200];
02748
02749
02750 int numatms;
02751 Tcl_Obj **data;
02752 if (Tcl_ListObjGetElements(interp, objv[2], &numatms, &data) != TCL_OK) {
02753 Tcl_AppendResult(interp, " measure energy: bad syntax", NULL);
02754 Tcl_AppendResult(interp, " Usage: measure energy bond|angle|dihed|imprp|vdw|elec {{<atomid1> ?<molid1>?} {<atomid2> ?<molid2>?} ...} ?molid <default molid>? [?frame <frame|all>? | ?first <first>? ?last <last>?]", NULL);
02755 return TCL_ERROR;
02756 }
02757
02758 if (numatms!=reqatoms) {
02759 sprintf(errstring, " measure energy %s: must specify exactly %i atoms in list", geomname, reqatoms);
02760 Tcl_AppendResult(interp, errstring, NULL);
02761 return TCL_ERROR;
02762 }
02763
02764 int first=-1, last=-1, frame=-1;
02765 double params[6];
02766 memset(params, 0, 6L*sizeof(double));
02767
02768 if (argc>4) {
02769 int i;
02770 for (i=3; i<argc-1; i+=2) {
02771 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
02772 if (!strupncmp(argvcur, "molid", CMDLEN)) {
02773 if (Tcl_GetIntFromObj(interp, objv[i+1], &defmolid) != TCL_OK) {
02774 Tcl_AppendResult(interp, " measure energy: bad molid", NULL);
02775 return TCL_ERROR;
02776 }
02777 } else if (!strupncmp(argvcur, "k", CMDLEN)) {
02778 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params) != TCL_OK) {
02779 Tcl_AppendResult(interp, " measure energy: bad force constant value", NULL);
02780 return TCL_ERROR;
02781 }
02782 } else if (!strupncmp(argvcur, "x0", CMDLEN)) {
02783 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+1) != TCL_OK) {
02784 Tcl_AppendResult(interp, " measure energy: bad equilibrium value", NULL);
02785 return TCL_ERROR;
02786 }
02787 } else if (!strupncmp(argvcur, "kub", CMDLEN)) {
02788 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+2) != TCL_OK) {
02789 Tcl_AppendResult(interp, " measure energy: bad Urey-Bradley force constant value", NULL);
02790 return TCL_ERROR;
02791 }
02792 } else if (!strupncmp(argvcur, "s0", CMDLEN)) {
02793 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+3) != TCL_OK) {
02794 Tcl_AppendResult(interp, " measure energy: bad Urey-Bradley equilibrium distance", NULL);
02795 return TCL_ERROR;
02796 }
02797 } else if (!strupncmp(argvcur, "n", CMDLEN)) {
02798 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+1) != TCL_OK) {
02799 Tcl_AppendResult(interp, " measure energy: bad dihedral periodicity", NULL);
02800 return TCL_ERROR;
02801 }
02802 } else if (!strupncmp(argvcur, "delta", CMDLEN)) {
02803 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+2) != TCL_OK) {
02804 Tcl_AppendResult(interp, " measure energy: bad dihedral phase shift", NULL);
02805 return TCL_ERROR;
02806 }
02807 } else if (!strupncmp(argvcur, "eps1", CMDLEN)) {
02808 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params) != TCL_OK) {
02809 Tcl_AppendResult(interp, " measure energy: bad vdw well depth", NULL);
02810 return TCL_ERROR;
02811 }
02812 } else if (!strupncmp(argvcur, "rmin1", CMDLEN)) {
02813 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+1) != TCL_OK) {
02814 Tcl_AppendResult(interp, " measure energy: bad vdw equilibrium distance", NULL);
02815 return TCL_ERROR;
02816 }
02817 } else if (!strupncmp(argvcur, "eps2", CMDLEN)) {
02818 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+2) != TCL_OK) {
02819 Tcl_AppendResult(interp, " measure energy: bad vdw well depth", NULL);
02820 return TCL_ERROR;
02821 }
02822 } else if (!strupncmp(argvcur, "rmin2", CMDLEN)) {
02823 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+3) != TCL_OK) {
02824 Tcl_AppendResult(interp, " measure energy: bad vdw equilibrium distance", NULL);
02825 return TCL_ERROR;
02826 }
02827 } else if (!strupncmp(argvcur, "q1", CMDLEN)) {
02828 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params) != TCL_OK) {
02829 Tcl_AppendResult(interp, " measure energy: bad charge value", NULL);
02830 return TCL_ERROR;
02831 }
02832 params[2]=1.0;
02833 } else if (!strupncmp(argvcur, "q2", CMDLEN)) {
02834 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+1) != TCL_OK) {
02835 Tcl_AppendResult(interp, " measure energy: bad charge value", NULL);
02836 return TCL_ERROR;
02837 }
02838 params[3]=1.0;
02839 } else if (!strupncmp(argvcur, "cutoff", CMDLEN)) {
02840 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+4) != TCL_OK) {
02841 Tcl_AppendResult(interp, " measure energy: bad electrostatic cutoff value", NULL);
02842 return TCL_ERROR;
02843 }
02844 } else if (!strupncmp(argvcur, "switchdist", CMDLEN)) {
02845 if (Tcl_GetDoubleFromObj(interp, objv[i+1], params+5) != TCL_OK) {
02846 Tcl_AppendResult(interp, " measure energy: bad switching distance value", NULL);
02847 return TCL_ERROR;
02848 }
02849 } else if (!strupncmp(argvcur, "first", CMDLEN)) {
02850 if (Tcl_GetIntFromObj(interp, objv[i+1], &first) != TCL_OK) {
02851 Tcl_AppendResult(interp, " measure energy: bad first frame value", NULL);
02852 return TCL_ERROR;
02853 }
02854 } else if (!strupncmp(argvcur, "last", CMDLEN)) {
02855 if (Tcl_GetIntFromObj(interp, objv[i+1], &last) != TCL_OK) {
02856 Tcl_AppendResult(interp, " measure energy: bad last frame value", NULL);
02857 return TCL_ERROR;
02858 }
02859 } else if (!strupncmp(argvcur, "frame", CMDLEN)) {
02860 if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "all")) {
02861 allframes = true;
02862 } else if (Tcl_GetIntFromObj(interp, objv[i+1], &frame) != TCL_OK) {
02863 Tcl_AppendResult(interp, " measure energy: bad frame value", NULL);
02864 return TCL_ERROR;
02865 }
02866 } else {
02867 Tcl_AppendResult(interp, " measure energy: invalid syntax, no such keyword: ", argvcur, NULL);
02868 return TCL_ERROR;
02869 }
02870 }
02871 }
02872
02873 if ((allframes || frame>=0) && (first>=0 || last>=0)) {
02874 Tcl_AppendResult(interp, "measure energy: Ambiguous syntax: You cannot specify a frame AND a frame range (using first or last).", NULL);
02875 Tcl_AppendResult(interp, "\nUsage:\nmeasure bond <molid1>/<atomid1> <molid2>/<atomid2> [?frame <frame|all>? | ?first <first>? ?last <last>?]", NULL);
02876 return TCL_ERROR;
02877 }
02878
02879 if (allframes) first=0;
02880
02881
02882 if (defmolid<0) defmolid = app->molecule_top();
02883
02884
02885 int i,numelem;
02886 Tcl_Obj **atmmol;
02887 for (i=0; i<numatms; i++) {
02888 if (Tcl_ListObjGetElements(interp, data[i], &numelem, &atmmol) != TCL_OK) {
02889 return TCL_ERROR;
02890 }
02891
02892 if (Tcl_GetIntFromObj(interp, atmmol[0], atmid+i) != TCL_OK) {
02893 Tcl_AppendResult(interp, " measure energy: bad atom index", NULL);
02894 return TCL_ERROR;
02895 }
02896
02897 if (numelem==2) {
02898 if (Tcl_GetIntFromObj(interp, atmmol[1], molid+i) != TCL_OK) {
02899 Tcl_AppendResult(interp, " measure energy: bad molid", NULL);
02900 return TCL_ERROR;
02901 }
02902 } else molid[i] = defmolid;
02903 }
02904
02905
02906
02907 ResizeArray<float> gValues(1024);
02908 int ret_val;
02909 ret_val = measure_energy(app->moleculeList, molid, atmid, reqatoms, &gValues, frame, first, last, defmolid, params, geomtype);
02910 if (ret_val<0) {
02911 printf("ERROR\n %s\n", measure_error(ret_val));
02912 Tcl_AppendResult(interp, measure_error(ret_val), NULL);
02913 return TCL_ERROR;
02914 }
02915
02916 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
02917 int numvalues = gValues.num();
02918 for (int count = 0; count < numvalues; count++) {
02919 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(gValues[count]));
02920 }
02921 Tcl_SetObjResult(interp, tcl_result);
02922
02923 return TCL_OK;
02924 }
02925
02926
02927
02928
02929
02930 static int vmd_measure_surface(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02931 if (argc!=5) {
02932 Tcl_WrongNumArgs(interp, 2, objv-1,
02933 (char *) "<sel> <gridsize> <radius> <depth>");
02934 return TCL_ERROR;
02935 }
02936
02937 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
02938 if (!sel) {
02939 Tcl_AppendResult(interp, "measure surface: no atom selection", NULL);
02940 return TCL_ERROR;
02941 }
02942
02943 const float *framepos = sel->coordinates(app->moleculeList);
02944 if (!framepos) return TCL_ERROR;
02945
02946 double gridsz;
02947 if (Tcl_GetDoubleFromObj(interp, objv[2], &gridsz) != TCL_OK)
02948 return TCL_ERROR;
02949
02950 double radius;
02951 if (Tcl_GetDoubleFromObj(interp, objv[3], &radius) != TCL_OK)
02952 return TCL_ERROR;
02953
02954 double depth;
02955 if (Tcl_GetDoubleFromObj(interp, objv[4], &depth) != TCL_OK)
02956 return TCL_ERROR;
02957
02958 int *surface;
02959 int n_surf;
02960
02961 int ret_val = measure_surface(sel, app->moleculeList, framepos,
02962 gridsz, radius, depth, &surface, &n_surf);
02963 if (ret_val < 0) {
02964 Tcl_AppendResult(interp, "measure surface: ", measure_error(ret_val));
02965 return TCL_ERROR;
02966 }
02967
02968 Tcl_Obj *surf_list = Tcl_NewListObj(0, NULL);
02969
02970 int i;
02971 for(i=0; i < n_surf; i++) {
02972 Tcl_ListObjAppendElement(interp, surf_list, Tcl_NewIntObj(surface[i]));
02973 }
02974 Tcl_SetObjResult(interp, surf_list);
02975 delete [] surface;
02976
02977 return TCL_OK;
02978 }
02979
02980
02981
02982
02983
02984 static int vmd_measure_pbc2onc_transform(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
02985 if (argc < 2) {
02986 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<center> [molid <default>] [frame <frame|last>]");
02987 return TCL_ERROR;
02988 }
02989
02990
02991 int ndim;
02992 Tcl_Obj **centerObj;
02993 if (Tcl_ListObjGetElements(interp, objv[1], &ndim, ¢erObj) != TCL_OK) {
02994 Tcl_AppendResult(interp, " measure pbc2onc: bad syntax", NULL);
02995 Tcl_AppendResult(interp, " Usage: measure pbc2onc <center> [molid <default>] [frame <frame|last>]", NULL);
02996 return TCL_ERROR;
02997 }
02998
02999 if (ndim!=3) {
03000 Tcl_AppendResult(interp, " measure pbc2onc: need three numbers for a vector", NULL);
03001 return TCL_ERROR;
03002 }
03003
03004 int i;
03005 double tmp;
03006 float center[3];
03007 for (i=0; i<3; i++) {
03008 if (Tcl_GetDoubleFromObj(interp, centerObj[i], &tmp) != TCL_OK) {
03009 Tcl_AppendResult(interp, " measure pbc2onc: non-numeric in center", NULL);
03010 return TCL_ERROR;
03011 }
03012 center[i] = (float)tmp;
03013 }
03014
03015 int molid = app->molecule_top();
03016 int frame = -2;
03017 if (argc>3) {
03018 for (i=2; i<argc; i+=2) {
03019 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
03020 if (!strupncmp(argvcur, "molid", CMDLEN)) {
03021
03022 if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "top")) {
03023
03024 } else if (Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
03025 Tcl_AppendResult(interp, " measure pbc2onc: bad molid", NULL);
03026 return TCL_ERROR;
03027 }
03028 } else if (!strupncmp(argvcur, "frame", CMDLEN)) {
03029 if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "last")) {
03030 frame=-1;
03031 } else if (Tcl_GetIntFromObj(interp, objv[i+1], &frame) != TCL_OK) {
03032 Tcl_AppendResult(interp, " measure pbc2onc: bad frame value", NULL);
03033 return TCL_ERROR;
03034 }
03035 } else {
03036 Tcl_AppendResult(interp, " measure pbc2onc: invalid syntax, no such keyword: ", argvcur, NULL);
03037 return TCL_ERROR;
03038 }
03039 }
03040 }
03041
03042
03043 Matrix4 transform;
03044 int ret_val = measure_pbc2onc(app->moleculeList, molid, frame, center, transform);
03045 if (ret_val < 0) {
03046 Tcl_AppendResult(interp, "measure pbc2onc: ", measure_error(ret_val), NULL);
03047 return TCL_ERROR;
03048 }
03049
03050 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
03051 for (i=0; i<4; i++) {
03052 Tcl_Obj *rowListObj = Tcl_NewListObj(0, NULL);
03053 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(transform.mat[i+0]));
03054 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(transform.mat[i+4]));
03055 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(transform.mat[i+8]));
03056 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(transform.mat[i+12]));
03057 Tcl_ListObjAppendElement(interp, tcl_result, rowListObj);
03058 }
03059 Tcl_SetObjResult(interp, tcl_result);
03060
03061 return TCL_OK;
03062 }
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094 static int vmd_measure_pbc_neighbors(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
03095 if (argc < 3) {
03096 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<center> <cutoff> ?sel <selection>? ?align <matrix>? ?molid <default>? ?frame <frame|last>? ?boundingbox PBC|{<mincoord> <maxcoord>}?");
03097 return TCL_ERROR;
03098 }
03099
03100
03101 int ndim;
03102 Tcl_Obj **centerObj;
03103 if (Tcl_ListObjGetElements(interp, objv[1], &ndim, ¢erObj) != TCL_OK) {
03104 Tcl_AppendResult(interp, " measure pbcneighbors: bad syntax", NULL);
03105 Tcl_AppendResult(interp, " Usage: measure pbcneighbors <center> <cutoff> [<sel <sel>] [align <matrix>] [molid <default>] [frame <frame|last>] [boundingbox <PBC|{<mincoord> <maxcoord>}>]", NULL);
03106 return TCL_ERROR;
03107 }
03108
03109 if (ndim!=3) {
03110 Tcl_AppendResult(interp, " measure pbcneighbors: need three numbers for a vector", NULL);
03111 return TCL_ERROR;
03112 }
03113
03114 int i;
03115 double tmp;
03116 float center[3];
03117 for (i=0; i<3; i++) {
03118 if (Tcl_GetDoubleFromObj(interp, centerObj[i], &tmp) != TCL_OK) {
03119 Tcl_AppendResult(interp, " measure pbcneighbors: non-numeric in center", NULL);
03120 return TCL_ERROR;
03121 }
03122 center[i] = float(tmp);
03123 }
03124
03125
03126 Tcl_Obj **cutoffObj;
03127 if (Tcl_ListObjGetElements(interp, objv[2], &ndim, &cutoffObj) != TCL_OK) {
03128 Tcl_AppendResult(interp, " measure pbcneighbors: bad syntax", NULL);
03129 Tcl_AppendResult(interp, " Usage: measure pbcneighbors <center> <cutoff> [<sel <sel>] [align <matrix>] [molid <default>] [frame <frame|last>] [boundingbox <PBC|{<mincoord> <maxcoord>}>]", NULL);
03130 return TCL_ERROR;
03131 }
03132
03133 if (ndim!=3 && ndim!=1) {
03134 Tcl_AppendResult(interp, " measure pbcneighbors: need either one or three numbers for cutoff", NULL);
03135 return TCL_ERROR;
03136 }
03137
03138 float cutoff[3];
03139 for (i=0; i<ndim; i++) {
03140 if (Tcl_GetDoubleFromObj(interp, cutoffObj[i], &tmp) != TCL_OK) {
03141 Tcl_AppendResult(interp, " measure pbcneighbors: non-numeric in cutoff", NULL);
03142 return TCL_ERROR;
03143 }
03144 cutoff[i] = float(tmp);
03145 }
03146
03147 if (ndim==1) { cutoff[2] = cutoff[1] = cutoff[0]; }
03148
03149 bool molidprovided=0;
03150 float *boxminmax=NULL;
03151 int molid = app->molecule_top();
03152 int frame = -2;
03153 AtomSel *sel = NULL;
03154 Matrix4 alignment;
03155 if (argc>4) {
03156 for (i=3; i<argc; i+=2) {
03157 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
03158 if (!strupncmp(argvcur, "sel", CMDLEN)) {
03159
03160 sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[i+1],NULL));
03161 if (!sel) {
03162 Tcl_AppendResult(interp, "measure pbcneighbors: invalid atom selection", NULL);
03163 return TCL_ERROR;
03164 }
03165 if (!app->molecule_valid_id(sel->molid())) {
03166 Tcl_AppendResult(interp, "measure pbcneighbors: ",
03167 measure_error(MEASURE_ERR_NOMOLECULE), NULL);
03168 return TCL_ERROR;
03169 }
03170 if (!sel->selected) {
03171 Tcl_AppendResult(interp, "measure pbcneighbors: selection contains no atoms.", NULL);
03172 return TCL_ERROR;
03173 }
03174 } else if (!strupncmp(argvcur, "molid", CMDLEN)) {
03175 if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "top")) {
03176
03177 } else if (Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
03178 Tcl_AppendResult(interp, " measure pbcneighbors: bad molid", NULL);
03179 return TCL_ERROR;
03180 }
03181 molidprovided = 1;
03182 } else if (!strupncmp(argvcur, "frame", CMDLEN)) {
03183 if (!strupcmp(Tcl_GetStringFromObj(objv[i+1],NULL), "last")) {
03184 frame=-1;
03185 } else if (Tcl_GetIntFromObj(interp, objv[i+1], &frame) != TCL_OK) {
03186 Tcl_AppendResult(interp, " measure pbcneighbors: bad frame value", NULL);
03187 return TCL_ERROR;
03188 }
03189 } else if (!strupncmp(argvcur, "align", CMDLEN)) {
03190
03191 if (tcl_get_matrix("measure pbcneighbors: ", interp, objv[i+1], alignment.mat) != TCL_OK) {
03192 return TCL_ERROR;
03193 }
03194 } else if (!strupncmp(argvcur, "boundingbox", CMDLEN)) {
03195
03196
03197 char *argv2 = Tcl_GetStringFromObj(objv[i+1],NULL);
03198 if (!strupncmp(argv2, "on", CMDLEN) || !strupncmp(argv2, "pbc", CMDLEN)) {
03199 boxminmax = new float[6];
03200 compute_pbcminmax(app->moleculeList, molid, frame, center, &alignment,
03201 boxminmax, boxminmax+3);
03202 } else {
03203
03204 int j, k, ncoor;
03205 Tcl_Obj **boxListObj;
03206 if (Tcl_ListObjGetElements(interp, objv[i+1], &ncoor, &boxListObj) != TCL_OK) {
03207 Tcl_AppendResult(interp, " measure pbcneighbors: invalid bounding box parameter", NULL);
03208 return TCL_ERROR;
03209 }
03210 if (ncoor!=2) {
03211 Tcl_AppendResult(interp, " measure pbcneighbors: need 2 points for bounding box", NULL);
03212 return TCL_ERROR;
03213 }
03214 int ndim = 0;
03215 double tmp;
03216 Tcl_Obj **boxObj;
03217 boxminmax = new float[6];
03218 for (j=0; j<2; j++) {
03219 if (Tcl_ListObjGetElements(interp, boxListObj[j], &ndim, &boxObj) != TCL_OK) {
03220 Tcl_AppendResult(interp, " measure pbcneighbors: bad syntax in boundingbox", NULL);
03221 return TCL_ERROR;
03222 }
03223
03224 for (k=0; k<3; k++) {
03225 if (Tcl_GetDoubleFromObj(interp, boxObj[k], &tmp) != TCL_OK) {
03226 Tcl_AppendResult(interp, " measure pbcneighbors: non-numeric in boundingbox", NULL);
03227 return TCL_ERROR;
03228 }
03229 boxminmax[3L*j+k] = (float)tmp;
03230 }
03231 }
03232 }
03233
03234 } else {
03235 Tcl_AppendResult(interp, " measure pbcneighbors: invalid syntax, no such keyword: ", argvcur, NULL);
03236 return TCL_ERROR;
03237 }
03238 }
03239 }
03240
03241
03242
03243 if (sel && !molidprovided) {
03244 molid = sel->molid();
03245 }
03246
03247 ResizeArray<float> extcoord_array;
03248 ResizeArray<int> indexmap_array;
03249
03250 int ret_val = measure_pbc_neighbors(app->moleculeList, sel, molid, frame, &alignment, center, cutoff, boxminmax, &extcoord_array, &indexmap_array);
03251 delete [] boxminmax;
03252
03253 if (ret_val < 0) {
03254 Tcl_AppendResult(interp, "measure pbcneighbors: ", measure_error(ret_val), NULL);
03255 return TCL_ERROR;
03256 }
03257 printf("measure pbcneighbors: %ld neighbor atoms found\n",
03258 long(indexmap_array.num()));
03259
03260 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
03261 Tcl_Obj *coorListObj = Tcl_NewListObj(0, NULL);
03262 Tcl_Obj *indexListObj = Tcl_NewListObj(0, NULL);
03263 for (i=0; i<indexmap_array.num(); i++) {
03264 Tcl_Obj *rowListObj = Tcl_NewListObj(0, NULL);
03265 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(extcoord_array[3L*i]));
03266 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(extcoord_array[3L*i+1]));
03267 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(extcoord_array[3L*i+2]));
03268 Tcl_ListObjAppendElement(interp, coorListObj, rowListObj);
03269 Tcl_ListObjAppendElement(interp, indexListObj, Tcl_NewIntObj(indexmap_array[i]));
03270 }
03271 Tcl_ListObjAppendElement(interp, tcl_result, coorListObj);
03272 Tcl_ListObjAppendElement(interp, tcl_result, indexListObj);
03273 Tcl_SetObjResult(interp, tcl_result);
03274
03275 return TCL_OK;
03276 }
03277
03278
03279
03280
03281
03282
03283
03284
03285 static int vmd_measure_inertia(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
03286 bool moments = FALSE;
03287 bool eigenvals = FALSE;
03288 if (argc < 2 || argc > 4) {
03289 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<selection> [moments] [eigenvals]");
03290 return TCL_ERROR;
03291 }
03292 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
03293 if (!sel) {
03294 Tcl_AppendResult(interp, "measure inertia: no atom selection", NULL);
03295 return TCL_ERROR;
03296 }
03297
03298 if (!app->molecule_valid_id(sel->molid())) {
03299 Tcl_AppendResult(interp, "measure inertia: ",
03300 measure_error(MEASURE_ERR_NOMOLECULE), NULL);
03301 return TCL_ERROR;
03302 }
03303
03304 if (argc>2) {
03305 int i;
03306 for (i=2; i<argc; i++) {
03307 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
03308
03309 if (argvcur[0]=='-') argvcur++;
03310
03311 if (!strupncmp(argvcur, "moments", CMDLEN)) {
03312 moments = TRUE;
03313 }
03314 else if (!strupncmp(argvcur, "eigenvals", CMDLEN)) {
03315 eigenvals = TRUE;
03316 }
03317 else {
03318 Tcl_AppendResult(interp, " measure inertia: unrecognized option\n", NULL);
03319 Tcl_AppendResult(interp, " Usage: measure inertia <selection> [moments] [eigenvals]", NULL);
03320 return TCL_ERROR;
03321 }
03322 }
03323 }
03324
03325 float priaxes[3][3];
03326 float itensor[4][4];
03327 float evalue[3], rcom[3];
03328 int ret_val = measure_inertia(sel, app->moleculeList, NULL, rcom, priaxes, itensor, evalue);
03329 if (ret_val < 0) {
03330 Tcl_AppendResult(interp, "measure inertia: ", measure_error(ret_val), NULL);
03331 return TCL_ERROR;
03332 }
03333
03334
03335 int i;
03336 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
03337
03338 Tcl_Obj *rcomObj = Tcl_NewListObj(0, NULL);
03339 Tcl_ListObjAppendElement(interp, rcomObj, Tcl_NewDoubleObj(rcom[0]));
03340 Tcl_ListObjAppendElement(interp, rcomObj, Tcl_NewDoubleObj(rcom[1]));
03341 Tcl_ListObjAppendElement(interp, rcomObj, Tcl_NewDoubleObj(rcom[2]));
03342 Tcl_ListObjAppendElement(interp, tcl_result, rcomObj);
03343
03344 Tcl_Obj *axesListObj = Tcl_NewListObj(0, NULL);
03345 for (i=0; i<3; i++) {
03346 Tcl_Obj *axesObj = Tcl_NewListObj(0, NULL);
03347 Tcl_ListObjAppendElement(interp, axesObj, Tcl_NewDoubleObj(priaxes[i][0]));
03348 Tcl_ListObjAppendElement(interp, axesObj, Tcl_NewDoubleObj(priaxes[i][1]));
03349 Tcl_ListObjAppendElement(interp, axesObj, Tcl_NewDoubleObj(priaxes[i][2]));
03350 Tcl_ListObjAppendElement(interp, axesListObj, axesObj);
03351 }
03352 Tcl_ListObjAppendElement(interp, tcl_result, axesListObj);
03353
03354 if (moments) {
03355 Tcl_Obj *momListObj = Tcl_NewListObj(0, NULL);
03356 for (i=0; i<3; i++) {
03357 Tcl_Obj *momObj = Tcl_NewListObj(0, NULL);
03358 Tcl_ListObjAppendElement(interp, momObj, Tcl_NewDoubleObj(itensor[i][0]));
03359 Tcl_ListObjAppendElement(interp, momObj, Tcl_NewDoubleObj(itensor[i][1]));
03360 Tcl_ListObjAppendElement(interp, momObj, Tcl_NewDoubleObj(itensor[i][2]));
03361 Tcl_ListObjAppendElement(interp, momListObj, momObj);
03362 }
03363 Tcl_ListObjAppendElement(interp, tcl_result, momListObj);
03364 }
03365
03366 if (eigenvals) {
03367 Tcl_Obj *eigvListObj = Tcl_NewListObj(0, NULL);
03368 Tcl_ListObjAppendElement(interp, eigvListObj, Tcl_NewDoubleObj(evalue[0]));
03369 Tcl_ListObjAppendElement(interp, eigvListObj, Tcl_NewDoubleObj(evalue[1]));
03370 Tcl_ListObjAppendElement(interp, eigvListObj, Tcl_NewDoubleObj(evalue[2]));
03371 Tcl_ListObjAppendElement(interp, tcl_result, eigvListObj);
03372 }
03373 Tcl_SetObjResult(interp, tcl_result);
03374
03375 return TCL_OK;
03376 }
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468 static int vmd_measure_symmetry(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
03469 if (argc<2) {
03470 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<sel> [element [<vector>]] [-tol <value>] [-nobonds] [-verbose <level>]");
03471 return TCL_ERROR;
03472 }
03473 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
03474 if (!sel) {
03475 Tcl_AppendResult(interp, "measure symmetry: no atom selection", NULL);
03476 return TCL_ERROR;
03477 }
03478 if (!app->molecule_valid_id(sel->molid())) {
03479 Tcl_AppendResult(interp, "measure symmetry: ",
03480 measure_error(MEASURE_ERR_NOMOLECULE), NULL);
03481 return TCL_ERROR;
03482 }
03483
03484 double sigma = 0.1;
03485 float axis[3];
03486 int checkelement = 0;
03487 int checkbonds = 1;
03488 int order = 0;
03489 int verbose = 1;
03490 int impose = 0;
03491 int imposeinvers = 0;
03492 int numimposeplan = 0;
03493 int numimposeaxes = 0;
03494 int numimposerref = 0;
03495 float *imposeplan = NULL;
03496 float *imposeaxes = NULL;
03497 float *imposerref = NULL;
03498 int *imposeaxesord = NULL;
03499 int *imposerreford = NULL;
03500 AtomSel *idealsel = NULL;
03501
03502 if (argc>2) {
03503 int bailout = 0;
03504 int i;
03505 for (i=2; (i<argc && !bailout); i++) {
03506 char *argvcur = Tcl_GetStringFromObj(objv[i],NULL);
03507
03508 if (argvcur[0]=='-') argvcur++;
03509
03510 if (!strupncmp(argvcur, "tol", CMDLEN)) {
03511 if (Tcl_GetDoubleFromObj(interp, objv[i+1], &sigma) != TCL_OK) {
03512 Tcl_AppendResult(interp, " measure symmetry: bad tolerance value", NULL);
03513 bailout = 1; continue;
03514 }
03515 i++;
03516 }
03517 else if (!strupncmp(argvcur, "verbose", CMDLEN)) {
03518 if (Tcl_GetIntFromObj(interp, objv[i+1], &verbose) != TCL_OK) {
03519 Tcl_AppendResult(interp, " measure symmetry: bad verbosity level value", NULL);
03520 bailout = 1; continue;
03521 }
03522 i++;
03523 }
03524 else if (!strupncmp(argvcur, "nobonds", CMDLEN)) {
03525 checkbonds = 0;
03526 }
03527 else if (!strupcmp(argvcur, "I")) {
03528 checkelement = 1;
03529 }
03530 else if (!strupncmp(argvcur, "plane", CMDLEN)) {
03531 if (tcl_get_vector(Tcl_GetStringFromObj(objv[i+1],NULL), axis, interp)!=TCL_OK) {
03532 bailout = 1; continue;
03533 }
03534 checkelement = 2;
03535 i++;
03536 }
03537 else if (!strupncmp(argvcur, "C", 1) || !strupncmp(argvcur, "S", 1)) {
03538 char *begptr = argvcur+1;
03539 char *endptr;
03540 order = strtol(begptr, &endptr, 10);
03541 if (endptr==begptr || *endptr!='\0') {
03542 Tcl_AppendResult(interp, " measure symmetry: bad symmetry element format (must be I, C*, S*, plane, where * is the order). ", NULL);
03543 bailout = 1; continue;
03544 }
03545
03546 if (tcl_get_vector(Tcl_GetStringFromObj(objv[i+1],NULL), axis, interp)!=TCL_OK) {
03547 bailout = 1; continue;
03548 }
03549
03550 if (!strupncmp(argvcur, "C", 1)) checkelement = 3;
03551 if (!strupncmp(argvcur, "S", 1)) checkelement = 4;
03552 i++;
03553 }
03554 else if (!strupncmp(argvcur, "idealsel", CMDLEN)) {
03555 idealsel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[i+1],NULL));
03556 if (!sel) {
03557 Tcl_AppendResult(interp, "measure symmetry: no atom selection for idealized coordinates", NULL);
03558 bailout = 1; continue;
03559 }
03560 if (idealsel->molid()!=sel->molid()) {
03561 Tcl_AppendResult(interp, "measure symmetry: selection and idealsel must be from the same molecule", NULL);
03562 bailout = 1; continue;
03563 }
03564 if (idealsel->selected<sel->selected) {
03565 Tcl_AppendResult(interp, "measure symmetry: selection must be a subset of idealsel", NULL);
03566 bailout = 1; continue;
03567 }
03568
03569 int j;
03570 for (j=0; j<sel->num_atoms; j++) {
03571 if (sel->on[j] && !idealsel->on[j]) {
03572 Tcl_AppendResult(interp, "measure symmetry: selection must be a subset of idealsel", NULL);
03573 bailout = 1; continue;
03574 }
03575 }
03576
03577 i++;
03578 }
03579 else if (!strupncmp(argvcur, "imposeinversion", CMDLEN)) {
03580 imposeinvers = 1;
03581 impose = 1;
03582 }
03583 else if (!strupncmp(argvcur, "imposeplanes", CMDLEN)) {
03584
03585 int nelem;
03586 Tcl_Obj **elemListObj;
03587 if (i+1>=argc ||
03588 Tcl_ListObjGetElements(interp, objv[i+1], &nelem, &elemListObj) != TCL_OK) {
03589 Tcl_AppendResult(interp, " measure symmetry: bad syntax for imposeplanes option", NULL);
03590 bailout = 1; continue;
03591 }
03592 float *elem = new float[3L*nelem];
03593 int k;
03594 for (k=0; k<nelem; k++) {
03595 int nobj;
03596 Tcl_Obj **vecObj;
03597 if (Tcl_ListObjGetElements(interp, elemListObj[k], &nobj, &vecObj) != TCL_OK) {
03598 delete [] elem;
03599 Tcl_AppendResult(interp, " measure symmetry: bad syntax for imposeplanes option", NULL);
03600 bailout = 1; continue;
03601 }
03602 if (nobj!=3) {
03603 delete [] elem;
03604 Tcl_AppendResult(interp, " measure symmetry imposeplanes: vector must have 3 elements", NULL);
03605 bailout = 1; continue;
03606 }
03607
03608 int m;
03609 for (m=0; m<3; m++) {
03610 double d;
03611 if (Tcl_GetDoubleFromObj(interp, vecObj[m], &d) != TCL_OK) {
03612 delete [] elem;
03613 bailout = 1; continue;
03614 }
03615 elem[3L*k+m] = (float)d;
03616 }
03617 }
03618 if (imposeplan) delete [] imposeplan;
03619 imposeplan = elem;
03620 numimposeplan = nelem;
03621 impose = 1;
03622 i++;
03623 }
03624 else if (!strupncmp(argvcur, "imposeaxes", CMDLEN) ||
03625 !strupncmp(argvcur, "imposerotref", CMDLEN)) {
03626
03627 int nelem;
03628 Tcl_Obj **elemListObj;
03629 if (i+1>=argc ||
03630 Tcl_ListObjGetElements(interp, objv[i+1], &nelem, &elemListObj) != TCL_OK ||
03631 nelem%2) {
03632 Tcl_AppendResult(interp, " measure symmetry: bad syntax for imposeaxes/imposerotref option", NULL);
03633 bailout = 1; continue;
03634 }
03635 nelem /= 2;
03636
03637 if (nelem<=0) {
03638 i++;
03639 continue;
03640 }
03641 float *elem = new float[3L*nelem];
03642 int *axorder = new int[nelem];
03643 int k;
03644 for (k=0; k<nelem; k++) {
03645 int nobj;
03646 Tcl_Obj **vecObj;
03647 if (Tcl_ListObjGetElements(interp, elemListObj[2L*k], &nobj, &vecObj) != TCL_OK) {
03648 delete [] elem;
03649 delete [] axorder;
03650 Tcl_AppendResult(interp, " measure symmetry impose: bad syntax for axis vector", NULL);
03651 bailout = 1; continue;
03652 }
03653 if (Tcl_GetIntFromObj(interp, elemListObj[2L*k+1], &axorder[k]) != TCL_OK) {
03654 delete [] elem;
03655 delete [] axorder;
03656 bailout = 1; continue;
03657 }
03658 if (nobj!=3) {
03659 delete [] elem;
03660 delete [] axorder;
03661 Tcl_AppendResult(interp, " measure symmetry impose: axis vector must have 3 elements", NULL);
03662 bailout = 1; continue;
03663 }
03664
03665 int m;
03666 for (m=0; m<3; m++) {
03667 double d;
03668 if (Tcl_GetDoubleFromObj(interp, vecObj[m], &d) != TCL_OK) {
03669 delete [] elem;
03670 delete [] axorder;
03671 bailout = 1; continue;
03672 }
03673 elem[3L*k+m] = (float)d;
03674 }
03675 }
03676 if (!strupncmp(argvcur, "imposeaxes", CMDLEN)) {
03677 if (imposeaxes) delete [] imposeaxes;
03678 if (imposeaxesord) delete [] imposeaxesord;
03679 imposeaxes = elem;
03680 imposeaxesord = axorder;
03681 numimposeaxes = nelem;
03682 } else if (!strupncmp(argvcur, "imposerotref", CMDLEN)) {
03683 if (imposerref) delete [] imposerref;
03684 if (imposerreford) delete [] imposerreford;
03685 imposerref = elem;
03686 imposerreford = axorder;
03687 numimposerref = nelem;
03688 }
03689
03690 impose = 1;
03691 i++;
03692 }
03693 else {
03694 Tcl_AppendResult(interp, " measure symmetry: unrecognized option ", NULL);
03695 Tcl_AppendResult(interp, argvcur);
03696 Tcl_AppendResult(interp, ".\n Usage: measure symmetry <selection> [element [<vector>]] [-tol <value>] [-nobonds] [-verbose <level>]", NULL);
03697 bailout = 1; continue;
03698 }
03699 }
03700
03701 if (bailout) {
03702 if (imposeplan) delete [] imposeplan;
03703 if (imposeaxes) delete [] imposeaxes;
03704 if (imposerref) delete [] imposerref;
03705 if (imposeaxesord) delete [] imposeaxesord;
03706 if (imposerreford) delete [] imposerreford;
03707 return TCL_ERROR;
03708 }
03709 }
03710
03711
03712 Symmetry sym = Symmetry(sel, app->moleculeList, verbose);
03713
03714
03715 sym.set_overlaptol(float(sigma));
03716
03717
03718 sym.set_checkbonds(checkbonds);
03719
03720 if (checkelement) {
03721
03722
03723 float overlap = 0.0;
03724 if (checkelement==1) {
03725 overlap = sym.score_inversion();
03726 }
03727 else if (checkelement==2) {
03728 overlap = sym.score_plane(axis);
03729 }
03730 else if (checkelement==3) {
03731 overlap = sym.score_axis(axis, order);
03732 }
03733 else if (checkelement==4) {
03734 overlap = sym.score_rotary_reflection(axis, order);
03735 }
03736
03737 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
03738 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(overlap));
03739 Tcl_SetObjResult(interp, tcl_result);
03740 return TCL_OK;
03741 }
03742
03743 if (impose) {
03744 sym.impose(imposeinvers, numimposeplan, imposeplan,
03745 numimposeaxes, imposeaxes, imposeaxesord,
03746 numimposerref, imposerref, imposerreford);
03747 if (imposeplan) delete [] imposeplan;
03748 if (imposeaxes) delete [] imposeaxes;
03749 if (imposerref) delete [] imposerref;
03750 if (imposeaxesord) delete [] imposeaxesord;
03751 if (imposerreford) delete [] imposerreford;
03752 }
03753
03754 int ret_val = sym.guess(float(sigma));
03755 if (ret_val < 0) {
03756 Tcl_AppendResult(interp, "measure symmetry: ", measure_error(ret_val), NULL);
03757 return TCL_ERROR;
03758 }
03759
03760 int natoms = sel->selected;
03761 Symmetry *s = &sym;
03762
03763 if (idealsel) {
03764 Symmetry *isym = new Symmetry(idealsel, app->moleculeList, verbose);
03765 isym->set_overlaptol(float(sigma));
03766 isym->set_checkbonds(checkbonds);
03767 int j;
03768 float *plane = new float[3L*sym.numplanes()];
03769 for (j=0; j<sym.numplanes(); j++) {
03770 vec_copy(&plane[3L*j], sym.plane(j));
03771 }
03772 int *axisorder = new int[sym.numaxes()];
03773 float *axis = new float[3L*sym.numaxes()];
03774 for (j=0; j<sym.numaxes(); j++) {
03775 axisorder[j] = sym.get_axisorder(j);
03776 vec_copy(&axis[3L*j], sym.axis(j));
03777 }
03778 int *rrorder = new int[sym.numrotreflect()];
03779 float *rraxis = new float[3L*sym.numrotreflect()];
03780 for (j=0; j<sym.numrotreflect(); j++) {
03781 rrorder[j] = sym.get_rotreflectorder(j);
03782 vec_copy(&rraxis[3L*j], sym.rotreflect(j));
03783 }
03784
03785 int k=0, m=0;
03786 for (j=0; j<sel->num_atoms; j++) {
03787 if (idealsel->on[j]) {
03788 if (sel->on[j]) {
03789 vec_copy(isym->idealpos(k), sym.idealpos(m));
03790 m++;
03791 }
03792 k++;
03793 }
03794 }
03795 isym->impose(sym.has_inversion(),
03796 sym.numplanes(), plane,
03797 sym.numaxes(), axis, axisorder,
03798 sym.numrotreflect(), rraxis, rrorder);
03799
03800 ret_val = isym->guess(float(sigma));
03801 if (ret_val < 0) {
03802 Tcl_AppendResult(interp, "measure symmetry: ", measure_error(ret_val), NULL);
03803 return TCL_ERROR;
03804 }
03805
03806 natoms = idealsel->selected;
03807 s = isym;
03808 }
03809
03810 int pgorder;
03811 char pointgroup[6];
03812 s->get_pointgroup(pointgroup, &pgorder);
03813
03814 int i;
03815 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
03816 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("pointgroup", -1));
03817 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj(pointgroup, -1));
03818 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("order", -1));
03819 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewIntObj(pgorder));
03820 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("rmsd", -1));
03821 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(s->get_rmsd()));
03822 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("elements", -1));
03823 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj(s->get_element_summary(), -1));
03824 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("missing", -1));
03825 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj(s->get_missing_elements(), -1));
03826 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("additional", -1));
03827 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj(s->get_additional_elements(), -1));
03828
03829 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("com", -1));
03830 Tcl_Obj *invObj = Tcl_NewListObj(0, NULL);
03831 float *com = s->center_of_mass();
03832 Tcl_ListObjAppendElement(interp, invObj, Tcl_NewDoubleObj(com[0]));
03833 Tcl_ListObjAppendElement(interp, invObj, Tcl_NewDoubleObj(com[1]));
03834 Tcl_ListObjAppendElement(interp, invObj, Tcl_NewDoubleObj(com[2]));
03835 Tcl_ListObjAppendElement(interp, tcl_result, invObj);
03836
03837 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("inertia", -1));
03838 Tcl_Obj *inertListListObj = Tcl_NewListObj(0, NULL);
03839 float *inertia = s->get_inertia_axes();
03840 float *eigenval = s->get_inertia_eigenvals();
03841 int *unique = s->get_inertia_unique();
03842 for (i=0; i<3; i++) {
03843 Tcl_Obj *inertObj = Tcl_NewListObj(0, NULL);
03844 Tcl_ListObjAppendElement(interp, inertObj, Tcl_NewDoubleObj(inertia[3L*i]));
03845 Tcl_ListObjAppendElement(interp, inertObj, Tcl_NewDoubleObj(inertia[3L*i+1]));
03846 Tcl_ListObjAppendElement(interp, inertObj, Tcl_NewDoubleObj(inertia[3L*i+2]));
03847 Tcl_Obj *inertListObj = Tcl_NewListObj(0, NULL);
03848 Tcl_ListObjAppendElement(interp, inertListObj, inertObj);
03849 Tcl_ListObjAppendElement(interp, inertListObj, Tcl_NewDoubleObj(eigenval[i]));
03850 Tcl_ListObjAppendElement(interp, inertListObj, Tcl_NewIntObj(unique[i]));
03851 Tcl_ListObjAppendElement(interp, inertListListObj, inertListObj);
03852 }
03853 Tcl_ListObjAppendElement(interp, tcl_result, inertListListObj);
03854
03855
03856 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("inversion", -1));
03857 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewIntObj(s->has_inversion()));
03858
03859
03860 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("axes", -1));
03861 Tcl_Obj *axesListListObj = Tcl_NewListObj(0, NULL);
03862 for (i=0; i<s->numaxes(); i++) {
03863 Tcl_Obj *axesObj = Tcl_NewListObj(0, NULL);
03864
03865 Tcl_ListObjAppendElement(interp, axesObj, Tcl_NewDoubleObj(s->axis(i)[0]));
03866 Tcl_ListObjAppendElement(interp, axesObj, Tcl_NewDoubleObj(s->axis(i)[1]));
03867 Tcl_ListObjAppendElement(interp, axesObj, Tcl_NewDoubleObj(s->axis(i)[2]));
03868 Tcl_Obj *axesListObj = Tcl_NewListObj(0, NULL);
03869 Tcl_ListObjAppendElement(interp, axesListObj, axesObj);
03870 Tcl_ListObjAppendElement(interp, axesListObj, Tcl_NewIntObj(s->get_axisorder(i)));
03871 int axistype = s->get_axistype(i);
03872 if (axistype & PRINCIPAL_AXIS &&
03873 !(!s->is_spherical_top() && (axistype & PERPENDICULAR_AXIS))) {
03874 Tcl_ListObjAppendElement(interp, axesListObj, Tcl_NewStringObj("principal", -1));
03875 } else if (!s->is_spherical_top() && (axistype & PERPENDICULAR_AXIS)) {
03876 Tcl_ListObjAppendElement(interp, axesListObj, Tcl_NewStringObj("perpendicular", -1));
03877 } else {
03878 Tcl_ListObjAppendElement(interp, axesListObj, Tcl_NewListObj(0, NULL));
03879 }
03880 Tcl_ListObjAppendElement(interp, axesListListObj, axesListObj);
03881 }
03882 Tcl_ListObjAppendElement(interp, tcl_result, axesListListObj);
03883
03884
03885 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("rotreflect", -1));
03886 Tcl_Obj *rraxesListListObj = Tcl_NewListObj(0, NULL);
03887 for (i=0; i<s->numrotreflect(); i++) {
03888 Tcl_Obj *axesObj = Tcl_NewListObj(0, NULL);
03889
03890 Tcl_ListObjAppendElement(interp, axesObj, Tcl_NewDoubleObj(s->rotreflect(i)[0]));
03891 Tcl_ListObjAppendElement(interp, axesObj, Tcl_NewDoubleObj(s->rotreflect(i)[1]));
03892 Tcl_ListObjAppendElement(interp, axesObj, Tcl_NewDoubleObj(s->rotreflect(i)[2]));
03893 Tcl_Obj *rraxesListObj = Tcl_NewListObj(0, NULL);
03894 Tcl_ListObjAppendElement(interp, rraxesListObj, axesObj);
03895 Tcl_ListObjAppendElement(interp, rraxesListObj, Tcl_NewIntObj(s->get_rotreflectorder(i)));
03896 Tcl_ListObjAppendElement(interp, rraxesListObj, Tcl_NewIntObj(s->get_rotrefltype(i)));
03897 Tcl_ListObjAppendElement(interp, rraxesListListObj, rraxesListObj);
03898 }
03899 Tcl_ListObjAppendElement(interp, tcl_result, rraxesListListObj);
03900
03901
03902 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("planes", -1));
03903 Tcl_Obj *planesListListObj = Tcl_NewListObj(0, NULL);
03904 for (i=0; i<s->numplanes(); i++) {
03905 Tcl_Obj *planesObj = Tcl_NewListObj(0, NULL);
03906
03907 Tcl_ListObjAppendElement(interp, planesObj, Tcl_NewDoubleObj(s->plane(i)[0]));
03908 Tcl_ListObjAppendElement(interp, planesObj, Tcl_NewDoubleObj(s->plane(i)[1]));
03909 Tcl_ListObjAppendElement(interp, planesObj, Tcl_NewDoubleObj(s->plane(i)[2]));
03910 Tcl_Obj *planesListObj = Tcl_NewListObj(0, NULL);
03911 Tcl_ListObjAppendElement(interp, planesListObj, planesObj);
03912 switch (s->get_planetype(i)) {
03913 case 1:
03914 Tcl_ListObjAppendElement(interp, planesListObj, Tcl_NewStringObj("vertical", -1));
03915 break;
03916 case 3:
03917 Tcl_ListObjAppendElement(interp, planesListObj, Tcl_NewStringObj("dihedral", -1));
03918 break;
03919 case 4:
03920 Tcl_ListObjAppendElement(interp, planesListObj, Tcl_NewStringObj("horizontal", -1));
03921 break;
03922 default:
03923 Tcl_ListObjAppendElement(interp, planesListObj, Tcl_NewListObj(0, NULL));
03924 }
03925 Tcl_ListObjAppendElement(interp, planesListListObj, planesListObj);
03926 }
03927 Tcl_ListObjAppendElement(interp, tcl_result, planesListListObj);
03928
03929
03930 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("ideal", -1));
03931 Tcl_Obj *idealcoorListObj = Tcl_NewListObj(0, NULL);
03932 for (i=0; i<natoms; i++) {
03933 Tcl_Obj *idealcoorObj = Tcl_NewListObj(0, NULL);
03934
03935 Tcl_ListObjAppendElement(interp, idealcoorObj, Tcl_NewDoubleObj(s->idealpos(i)[0]));
03936 Tcl_ListObjAppendElement(interp, idealcoorObj, Tcl_NewDoubleObj(s->idealpos(i)[1]));
03937 Tcl_ListObjAppendElement(interp, idealcoorObj, Tcl_NewDoubleObj(s->idealpos(i)[2]));
03938 Tcl_ListObjAppendElement(interp, idealcoorListObj, idealcoorObj);
03939 }
03940 Tcl_ListObjAppendElement(interp, tcl_result, idealcoorListObj);
03941
03942 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("unique", -1));
03943 Tcl_Obj *uniquecoorListObj = Tcl_NewListObj(0, NULL);
03944 for (i=0; i<natoms; i++) {
03945 if (!s->get_unique_atom(i)) continue;
03946 Tcl_ListObjAppendElement(interp, uniquecoorListObj, Tcl_NewIntObj(i));
03947 }
03948 Tcl_ListObjAppendElement(interp, tcl_result, uniquecoorListObj);
03949
03950 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("orient", -1));
03951 Matrix4 *orient = s->get_orientation();
03952 Tcl_Obj *matrixObj = Tcl_NewListObj(0, NULL);
03953 for (i=0; i<4; i++) {
03954 Tcl_Obj *rowObj = Tcl_NewListObj(0, NULL);
03955 Tcl_ListObjAppendElement(interp, rowObj, Tcl_NewDoubleObj(orient->mat[i+0]));
03956 Tcl_ListObjAppendElement(interp, rowObj, Tcl_NewDoubleObj(orient->mat[i+4]));
03957 Tcl_ListObjAppendElement(interp, rowObj, Tcl_NewDoubleObj(orient->mat[i+8]));
03958 Tcl_ListObjAppendElement(interp, rowObj, Tcl_NewDoubleObj(orient->mat[i+12]));
03959 Tcl_ListObjAppendElement(interp, matrixObj, rowObj);
03960 }
03961 Tcl_ListObjAppendElement(interp, tcl_result, matrixObj);
03962
03963 Tcl_SetObjResult(interp, tcl_result);
03964 if (idealsel) {
03965 delete s;
03966 }
03967 return TCL_OK;
03968
03969 }
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980 static int vmd_measure_trans_overlap(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
03981 if (argc!=3 && argc!=5) {
03982 Tcl_WrongNumArgs(interp, 2, objv-1, (char *) "<sel> <matrix> [-sigma <value>]");
03983 return TCL_ERROR;
03984 }
03985 AtomSel *sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
03986 if (!sel) {
03987 Tcl_AppendResult(interp, "measure transoverlap: no atom selection", NULL);
03988 return TCL_ERROR;
03989 }
03990 if (!app->molecule_valid_id(sel->molid())) {
03991 Tcl_AppendResult(interp, "measure transoverlap: ",
03992 measure_error(MEASURE_ERR_NOMOLECULE), NULL);
03993 return TCL_ERROR;
03994 }
03995
03996
03997 Matrix4 trans;
03998 if (tcl_get_matrix("measure transoverlap: ",interp,objv[2], trans.mat) != TCL_OK) {
03999 return TCL_ERROR;
04000 }
04001
04002 double sigma = 0.1;
04003 if (argc==5) {
04004 if (!strupncmp(Tcl_GetStringFromObj(objv[3],NULL), "-sigma", CMDLEN)) {
04005 if (Tcl_GetDoubleFromObj(interp, objv[4], &sigma) != TCL_OK) {
04006 Tcl_AppendResult(interp, " measure transoverlap: bad sigma value", NULL);
04007 return TCL_ERROR;
04008 }
04009 } else {
04010 Tcl_AppendResult(interp, " measure transoverlap: unrecognized option\n", NULL);
04011 Tcl_AppendResult(interp, " Usage: measure transoverlap <sel> <matrix> [-sigma <value>]", NULL);
04012 return TCL_ERROR;
04013 }
04014 }
04015
04016 int maxnatoms = 100;
04017 float overlap;
04018 int ret_val = measure_trans_overlap(sel, app->moleculeList, &trans,
04019 float(sigma), NOSKIP_IDENTICAL,
04020 maxnatoms, overlap);
04021 if (ret_val < 0) {
04022 Tcl_AppendResult(interp, "measure transoverlap: ", measure_error(ret_val), NULL);
04023 return TCL_ERROR;
04024 }
04025
04026 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
04027 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewDoubleObj(overlap));
04028 Tcl_SetObjResult(interp, tcl_result);
04029
04030 return TCL_OK;
04031 }
04032
04033
04034
04035
04036
04037
04038 int vmd_measure_volinterior(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
04039 int verbose = 0;
04040 int recognized=0;
04041 if (argc < 3) {
04042
04043 Tcl_SetResult(interp, (char *) "usage: volinterior "
04044 " <selection1> [options]\n"
04045 "-res (default 10.0)\n"
04046 "-spacing (default res/3)\n"
04047 "-loadmap (load synth map)\n"
04048 "-probmap (compute and load probability map)\n"
04049 " --> -count_pmap (return percentile-based voxel counts)\n"
04050 "-discretize [float cutoff] (creates discrete map with cutoff probability)\n"
04051 "-mol molid [default: top]\n"
04052 "-vol volid [0]\n"
04053 "-nrays number of rays to cast [6]\n"
04054 "-isovalue [float: 1.0]\n"
04055 "-verbose\n"
04056 "-overwrite volid\n",
04057 TCL_STATIC);
04058 return TCL_ERROR;
04059 }
04060
04061
04062 AtomSel *sel = NULL;
04063 sel = tcl_commands_get_sel(interp, Tcl_GetStringFromObj(objv[1],NULL));
04064 if (!sel) {
04065 Tcl_AppendResult(interp, "volinterior: no atom selection.", NULL);
04066 return TCL_ERROR;
04067 }
04068 if (!sel->selected) {
04069 Tcl_AppendResult(interp, "volinterior: no atoms selected.", NULL);
04070 return TCL_ERROR;
04071 }
04072 if (!app->molecule_valid_id(sel->molid())) {
04073 Tcl_AppendResult(interp, "invalid mol id.", NULL);
04074 return TCL_ERROR;
04075 }
04076 int loadsynthmap = 0;
04077 int loadpmap=0;
04078 int count_pmap=0;
04079 int print_raydirs=0;
04080 int molid = -1;
04081 int volid = -1;
04082 int volidOverwrite = -1;
04083 int overwrite=0;
04084 int nrays=6;
04085 long Nout = 0;
04086 float isovalue=1.0;
04087 float proCutoff=0.90f;
04088 int process=0;
04089 float radscale;
04090 double resolution = 10.0;
04091 double gspacing;
04092 MoleculeList *mlist = app->moleculeList;
04093 Molecule *mymol = mlist->mol_from_id(sel->molid());
04094
04095 for (int i=2; i < argc; i++) {
04096 recognized=0;
04097 char *opt = Tcl_GetStringFromObj(objv[i], NULL);
04098 if (!strcmp(opt, "volinterior")) {
04099 recognized=1;
04100 }
04101 if (!strcmp(opt, "-mol")) {
04102 if (i == argc-1) {
04103 Tcl_AppendResult(interp, "No molid specified",NULL);
04104 return TCL_ERROR;
04105 } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
04106 Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
04107 return TCL_ERROR;
04108 }
04109 recognized=1;
04110 }
04111 if (!strcmp(opt, "-probmap")) {
04112 loadpmap=1;
04113 recognized=1;
04114 }
04115 if (!strcmp(opt, "-checkrays")) {
04116 print_raydirs=1;
04117 recognized=1;
04118 }
04119 if (!strcmp(opt, "-count_pmap")) {
04120 count_pmap=1;
04121 recognized=1;
04122 }
04123 if (!strcmp(opt, "-discretize")) {
04124 double tcutoff;
04125 if (i==argc-1) {
04126 Tcl_AppendResult(interp, "No cutoff probability given for -discretize flag",NULL);
04127 return TCL_ERROR;
04128 } else if (Tcl_GetDoubleFromObj(interp, objv[i+1], &tcutoff)!=TCL_OK) {
04129 Tcl_AppendResult(interp, "\n Cutoff probability for -discretize flag incorrectly specified.",NULL);
04130 return TCL_ERROR;
04131 }
04132 proCutoff=(float)tcutoff;
04133 recognized=1;
04134 process=1;
04135 }
04136 if (!strcmp(opt, "-vol")) {
04137 if (i == argc-1){
04138 Tcl_AppendResult(interp, "No volume id specified",NULL);
04139 return TCL_ERROR;
04140 } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &volid) != TCL_OK) {
04141 Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
04142 return TCL_ERROR;
04143 }
04144 recognized=1;
04145 }
04146
04147 if (!strcmp(opt, "-overwrite")) {
04148 if (i == argc-1){
04149 Tcl_AppendResult(interp, "No volume id specified",NULL);
04150 return TCL_ERROR;
04151 } else if (Tcl_GetIntFromObj(interp, objv[i+1], &volidOverwrite) != TCL_OK) {
04152 Tcl_AppendResult(interp, "\n volume id incorrectly specified",NULL);
04153 return TCL_ERROR;
04154 }
04155 overwrite=1;
04156 recognized=1;
04157 }
04158
04159
04160 if (!strcmp(opt, "-loadmap")) {
04161 loadsynthmap = 1;
04162 recognized=1;
04163 }
04164 if (!strcmp(opt, "-mol")) {
04165 if (i == argc-1) {
04166 Tcl_AppendResult(interp, "No molid specified",NULL);
04167 return TCL_ERROR;
04168 } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &molid) != TCL_OK) {
04169 Tcl_AppendResult(interp, "\n molid incorrectly specified",NULL);
04170 return TCL_ERROR;
04171 }
04172 recognized=1;
04173 }
04174 if (!strcmp(opt, "-res")) {
04175 if (i == argc-1) {
04176 Tcl_AppendResult(interp, "No resolution specified",NULL);
04177 return TCL_ERROR;
04178 } else if (Tcl_GetDoubleFromObj(interp, objv[i+1], &resolution) != TCL_OK) {
04179 Tcl_AppendResult(interp, "\nResolution incorrectly specified",NULL);
04180 return TCL_ERROR;
04181 }
04182 recognized=1;
04183 }
04184 if (!strcmp(opt, "-spacing")) {
04185 if (i == argc-1) {
04186 Tcl_AppendResult(interp, "No spacing specified",NULL);
04187 return TCL_ERROR;
04188 } else if ( Tcl_GetDoubleFromObj(interp, objv[i+1], &gspacing) != TCL_OK) {
04189 Tcl_AppendResult(interp, "\nspacing incorrectly specified",NULL);
04190 return TCL_ERROR;
04191 }
04192 recognized=1;
04193 }
04194
04195 if (!strcmp(opt,"-nrays")) {
04196 if (i == argc-1) {
04197 Tcl_AppendResult(interp, "No number of rays specified",NULL);
04198 return TCL_ERROR;
04199 } else if ( Tcl_GetIntFromObj(interp, objv[i+1], &nrays) != TCL_OK) {
04200 Tcl_AppendResult(interp, "\n number of rays incorrectly specified",NULL);
04201 return TCL_ERROR;
04202 }
04203 recognized=1;
04204 }
04205
04206 if (!strcmp(opt,"-isovalue")) {
04207 double tmp;
04208 if (i == argc-1) {
04209 Tcl_AppendResult(interp,"No isovalue specified",NULL);
04210 return TCL_ERROR;
04211 } else if (Tcl_GetDoubleFromObj(interp,objv[i+1],&tmp) != TCL_OK) {
04212 Tcl_AppendResult(interp,"\n Isovalue incorrectly specified", NULL);
04213 return TCL_ERROR;
04214 }
04215 isovalue=(float) tmp;
04216 recognized=1;
04217 }
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230 if (!strcmp(opt, "-verbose") || (getenv("VMDVOLINVERBOSE") != NULL)) {
04231 verbose = 1;
04232 recognized=1;
04233 }
04234
04235 if (recognized==0) {
04236
04237 if (isdigit(opt[0]) || isfloat(opt)) {
04238 continue;
04239 } else {
04240 Tcl_AppendResult(interp,"\n unrecognized option: '",opt,"'",NULL);
04241 return TCL_ERROR;
04242 }
04243 }
04244 }
04245
04246 if ((process||count_pmap) && !loadpmap) {
04247 Tcl_AppendResult(interp,"\n Cannot give -process or -count_pmap flags given without -probmap!",NULL);
04248 return TCL_ERROR;
04249 }
04250
04251 Molecule *volmolOverwrite = NULL;
04252 VolumetricData *volmapOverwrite = NULL;
04253 Molecule *pmolOverwrite=NULL;
04254 VolumetricData *pmapOverwrite=NULL;
04255 if (overwrite==1) {
04256 if (loadpmap!=1) {
04257 volmolOverwrite = mlist->mol_from_id(molid);
04258 volmapOverwrite = volmolOverwrite->modify_volume_data(volidOverwrite);
04259 if(volmapOverwrite==NULL) {
04260 Tcl_AppendResult(interp, "\n no overwrite volume correctly specified",NULL);
04261 return TCL_ERROR;
04262 }
04263 } else {
04264 pmolOverwrite=mlist->mol_from_id(molid);
04265 pmapOverwrite=pmolOverwrite->modify_volume_data(volidOverwrite);
04266 if (pmapOverwrite==NULL) {
04267 Tcl_AppendResult(interp,"\n no pmap overwrite volume correctly specified",NULL);
04268 return TCL_ERROR;
04269 }
04270 }
04271 }
04272
04273 VolumetricData *pmapT = NULL;
04274 VolumetricData *procmap = NULL;
04275 VolumetricData *pmap = NULL;
04276 VolumetricData *target = NULL;
04277 VolumetricData *volmapA = NULL;
04278
04279
04280 const float *framepos = sel->coordinates(app->moleculeList);
04281 const float *radii = mymol->radius();
04282 radscale= 0.2f * float(resolution);
04283 if (gspacing == 0) {
04284 gspacing=resolution*0.33;
04285 }
04286
04287 int quality=0;
04288 QuickSurf *qs = new QuickSurf();
04289 if (resolution >= 9)
04290 quality = 0;
04291 else
04292 quality = 3;
04293
04294 if (molid != -1 && volid != -1 ) {
04295 Molecule *volmol = mlist->mol_from_id(molid);
04296 volmapA = (VolumetricData *) volmol->get_volume_data(volid);
04297 if (volmapA==NULL) {
04298 Tcl_AppendResult(interp, "\n no target volume correctly specified", NULL);
04299 return TCL_ERROR;
04300 }
04301 } else {
04302 if (verbose) printf("\n Calculating grid ... \n");
04303 int cuda_err=-1;
04304 #if defined(VMDCUDA)
04305 cuda_err = vmd_cuda_calc_density(sel, app->moleculeList, quality,
04306 radscale, gspacing, &volmapA,
04307 NULL, NULL, verbose);
04308 #endif
04309 if (cuda_err == -1 ) {
04310 if (verbose) printf("Using CPU version of the code ... \n");
04311 volmapA = qs->calc_density_map(sel, mymol, framepos, radii,
04312 quality, radscale, float(gspacing));
04313 }
04314 if (verbose) printf("Done.\n");
04315 }
04316
04317 if (volmapA == NULL) {
04318 Tcl_AppendResult(interp, "\n no test volume or molid correctly specified",NULL);
04319 return TCL_ERROR;
04320 }
04321 target=CreateEmptyGrid(volmapA);
04322
04323 if (loadpmap == 1) {
04324 pmapT = CreateProbGrid(volmapA);
04325 }
04326
04327
04328
04329
04330
04331
04332
04333 #if 0
04334 float rayDir[3] = {1,0,0};
04335 Nout += RaycastGrid(volmapA,target,isovalue,rayDir);
04336 rayDir[0] = -1; rayDir[1]=0; rayDir[2]=0;
04337 Nout += RaycastGrid(volmapA,target,isovalue,rayDir);
04338 rayDir[0] = 0; rayDir[1]=1; rayDir[2]=0;
04339 Nout += RaycastGrid(volmapA,target,isovalue,rayDir);
04340 rayDir[0] = 0; rayDir[1]=-1; rayDir[2]=0;
04341 Nout += RaycastGrid(volmapA,target,isovalue,rayDir);
04342 rayDir[0] = 0; rayDir[1]=0; rayDir[2]=1;
04343 Nout += RaycastGrid(volmapA,target,isovalue,rayDir);
04344 rayDir[0] = 0; rayDir[1]=0; rayDir[2]=-1;
04345 Nout += RaycastGrid(volmapA,target,isovalue,rayDir);
04346 #endif
04347 #if 0
04348 if (verbose) printf("Marking down boundary.\n");
04349 long nVoxIso=markIsoGrid(volmapA, target,isovalue);
04350 if (verbose) printf("Casting rays ...\n");
04351 float rayDir[3] = {0.1f,0.1f,1.0f};
04352 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04353 if (verbose) printf("Dir 1 %ld \n",Nout);
04354 rayDir[0] = -0.1f; rayDir[1]=-0.1f; rayDir[2]=-1.0f;
04355 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04356 if (verbose) printf("Dir 2 %ld \n",Nout);
04357 rayDir[0] = 0.1f; rayDir[1]=1.0f; rayDir[2]=0.1f;
04358 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04359 if (verbose) printf("Dir 3 %ld \n",Nout);
04360 rayDir[0] = -0.1f; rayDir[1]=-1.0f; rayDir[2]=-0.1f;
04361 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04362 if (verbose) printf("Dir 4 %ld \n",Nout);
04363 rayDir[0] = 1.0f; rayDir[1]=0.1f; rayDir[2]=0.1f;
04364 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04365 if (verbose) printf("Dir 5 %ld \n",Nout);
04366 rayDir[0] = -1.0f; rayDir[1]=-0.1f; rayDir[2]=-0.1f;
04367 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04368 if (verbose) printf("Dir 6 %ld \n",Nout);
04369 rayDir[0] = -0.5f; rayDir[1]=-0.5f; rayDir[2]=-0.5f;
04370 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04371 if (verbose) printf("Dir 7 %ld \n",Nout);
04372 rayDir[0] = 0.5f; rayDir[1]=0.5f; rayDir[2]=0.5f;
04373 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04374 if (verbose) printf("Dir 9 %ld \n",Nout);
04375 rayDir[0] = -0.5f; rayDir[1]=0.5f; rayDir[2]=0.5f;
04376 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04377 if (verbose) printf("Dir 10 %ld \n",Nout);
04378 rayDir[0] = 0.5f; rayDir[1]=-0.5f; rayDir[2]=0.5f;
04379 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04380 if (verbose) printf("Dir 11 %ld \n",Nout);
04381 rayDir[0] = 0.5f; rayDir[1]=0.5f; rayDir[2]=-0.5f;
04382 Nout += volin_threaded(volmapA,target,isovalue,rayDir);
04383 if (verbose) printf("Dir 12 %ld \n",Nout);
04384 #endif
04385 if (verbose) printf("Marking down boundary.\n");
04386 long nVoxIso=markIsoGrid(volmapA, target,isovalue);
04387 float rayDir[3] = {0.1f,0.1f,1.0f};
04388 static const float RAND_MAX_INV = 1.0f/float(VMD_RAND_MAX);
04389
04390 float *poisson_set = new float[(nrays+1)*2];
04391 int numcandidates=40;
04392 int converged=poisson_sample_on_sphere(poisson_set,nrays,numcandidates,verbose);
04393 if (converged==0) {
04394 if (verbose) {
04395 printf("Poisson disk sampler failed for measure volinterior!\n");
04396 printf("... continuing with standard ray direction generator.\n");
04397 }
04398 }
04399
04400 if (print_raydirs && converged)
04401 print_xyz(poisson_set,nrays);
04402
04403 if (verbose) printf("Casting rays...\n");
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415 float sine1, cosine1, sine2, cosine2;
04416 for (int ray=0; ray < nrays; ray++) {
04417 float u1 = (float) vmd_random();
04418 float u2 = (float) vmd_random();
04419 float z = 2.0f*u1*RAND_MAX_INV -1.0f;
04420 float phi = (float) (2.0f*VMD_PI*u2*RAND_MAX_INV);
04421 float R = sqrtf(1.0f-z*z);
04422 if (converged==1) {
04423 sincosf(poisson_set[ray*2+0],&sine1,&cosine1);
04424 sincosf(poisson_set[ray*2+1],&sine2,&cosine2);
04425 rayDir[0]=cosine1*sine2;
04426 rayDir[1]=sine1*sine2;
04427 rayDir[2]=cosine2;
04428 } else {
04429 sincosf(phi,&sine1,&cosine1);
04430 rayDir[0]=R*cosine1;
04431 rayDir[1]=R*sine1;
04432 rayDir[2]=z;
04433 }
04434
04435
04436
04437
04438
04439 if (loadpmap == 1) {
04440 Nout += volin_threaded_prob(volmapA, target, pmapT, isovalue, rayDir);
04441 } else {
04442 Nout += volin_threaded(volmapA, target, isovalue, rayDir);
04443 }
04444
04445 if (verbose) printf("Ray(%d) (%4.3f %4.3f %4.3f). Voxels : %ld \n",ray+1,rayDir[0],rayDir[1],rayDir[2],Nout);
04446 }
04447 if (verbose) printf("Done.\n");
04448
04449 delete [] poisson_set;
04450
04451 if (verbose) printf("Counting voxels above isovalue ...\n");
04452
04453 Nout=countIsoGrids(target,EXTERIORVOXEL);
04454 long nIn=countIsoGrids(target,INTERIORVOXEL);
04455
04456 if (loadsynthmap == 1 ) {
04457 app->molecule_add_volumetric(molid, volmapA->name, volmapA->origin,
04458 volmapA->xaxis, volmapA->yaxis, volmapA->zaxis,
04459 volmapA->xsize, volmapA->ysize, volmapA->zsize,
04460 volmapA->data);
04461 volmapA->compute_volume_gradient();
04462 volmapA->data = NULL;
04463 }
04464
04465 if (overwrite != 1 ) {
04466 if (loadpmap==1) {
04467 if (verbose) printf("Normalizing probability map ...\n");
04468 pmap = normalize_pmap(pmapT, nrays);
04469 app->molecule_add_volumetric(molid, pmap->name, pmap->origin,
04470 pmap->xaxis, pmap->yaxis, pmap->zaxis,
04471 pmap->xsize, pmap->ysize, pmap->zsize,
04472 pmap->data);
04473 pmap->compute_volume_gradient();
04474 } else {
04475 app->molecule_add_volumetric(molid, target->name, target->origin,
04476 target->xaxis, target->yaxis, target->zaxis,
04477 target->xsize, target->ysize, target->zsize,
04478 target->data);
04479 target->compute_volume_gradient();
04480 target->data = NULL;
04481 }
04482 } else {
04483 if (loadpmap==1) {
04484 if (verbose) printf("Normalizing probability map ...\n");
04485 pmap = normalize_pmap(pmapT, nrays);
04486 if (verbose) printf("Overwriting volume...\n");
04487 pmapOverwrite->name=pmap->name;
04488 pmapOverwrite->xsize=pmap->xsize;
04489 pmapOverwrite->ysize=pmap->ysize;
04490 pmapOverwrite->zsize=pmap->zsize;
04491 pmapOverwrite->data=pmap->data;
04492 pmap->data=NULL;
04493 pmapOverwrite->compute_volume_gradient();
04494 if (verbose) printf("Done!\n");
04495 } else {
04496 if (verbose) printf("Overwriting volume ... \n");
04497 volmapOverwrite->name = target -> name;
04498 volmapOverwrite->xsize = target->xsize;
04499 volmapOverwrite->ysize = target->ysize;
04500 volmapOverwrite->zsize = target->zsize;
04501 volmapOverwrite->data = target->data;
04502 target->data=NULL;
04503 volmapOverwrite->compute_volume_gradient();
04504 if (verbose) printf("Done.\n ");
04505 }
04506 }
04507
04508 if ((loadpmap&&process)&&pmap->data!=NULL) {
04509
04510 procmap=process_pmap(pmap, proCutoff);
04511 app->molecule_add_volumetric(molid, procmap->name, procmap->origin,
04512 procmap->xaxis, procmap->yaxis, procmap->zaxis,
04513 procmap->xsize, procmap->ysize, procmap->zsize, procmap->data);
04514 procmap->compute_volume_gradient();
04515 procmap->data=NULL;
04516 if (verbose) printf("Loaded processed map\n");
04517 } else if ((loadpmap&&process)&&pmapOverwrite->data!=NULL) {
04518 procmap=process_pmap(pmapOverwrite, proCutoff);
04519 app->molecule_add_volumetric(molid, procmap->name, procmap->origin,
04520 procmap->xaxis, procmap->yaxis, procmap->zaxis,
04521 procmap->xsize, procmap->ysize, procmap->zsize, procmap->data);
04522 procmap->compute_volume_gradient();
04523 procmap->data=NULL;
04524 if (verbose) printf("Loaded processed map (they don't overwrite).\n");
04525 }
04526
04527 if (count_pmap==1 && pmap->data!=NULL) {
04528 if (loadpmap!=1) {
04529 printf("-count_pmap flag specified without -probmap!\n");
04530 return TCL_ERROR;
04531 } else {
04532 long Pvol=0;
04533 float currProb=0.0f;
04534 Tcl_Obj *analysis=Tcl_NewListObj(0,NULL);
04535 for (int c=0; c<10; c++) {
04536 currProb+=0.1f;
04537 if (c==9) currProb=((float)nrays-((float)nrays*0.01f))/(float)nrays;
04538 Pvol=vol_probability(pmap, currProb, float(gspacing));
04539 Tcl_ListObjAppendElement(interp, analysis, Tcl_NewLongObj(Pvol));
04540 }
04541 Tcl_SetObjResult(interp,analysis);
04542 if (molid != -1 && volid != -1 ) {
04543 target->data = NULL;
04544 pmap->data = NULL;
04545 } else {
04546 delete pmapT;
04547 delete qs;
04548 delete volmapA;
04549 }
04550
04551 return TCL_OK;
04552 }
04553 } else if (count_pmap==1 && overwrite==1 && pmapOverwrite->data!=NULL) {
04554 long Pvol=0;
04555 float currProb=0.0f;
04556 Tcl_Obj *analysis=Tcl_NewListObj(0,NULL);
04557 for (int c=0; c<10; c++) {
04558 currProb+=0.1f;
04559 if (c==9) currProb=((float)nrays-((float)nrays*0.01f))/(float)nrays;
04560 Pvol=vol_probability(pmapOverwrite, currProb, float(gspacing));
04561 Tcl_ListObjAppendElement(interp, analysis, Tcl_NewLongObj(Pvol));
04562 }
04563 Tcl_SetObjResult(interp,analysis);
04564 if (molid != -1 && volid != -1 ) {
04565 target->data = NULL;
04566 pmap->data = NULL;
04567 } else {
04568 delete pmapT;
04569 delete qs;
04570 delete volmapA;
04571 }
04572
04573 return TCL_OK;
04574 }
04575
04576 if (molid != -1 && volid != -1 ) {
04577 target->data = NULL;
04578 procmap->data=NULL;
04579 pmap->data = NULL;
04580 } else {
04581 delete pmapT;
04582 delete qs;
04583 delete volmapA;
04584 }
04585
04586 long Ntotal = target->xsize * target->ysize * target->zsize;
04587
04588
04589 Tcl_Obj *tcl_result = Tcl_NewListObj(0,NULL);
04590 Tcl_ListObjAppendElement(interp,tcl_result,Tcl_NewLongObj(Ntotal));
04591 Tcl_ListObjAppendElement(interp,tcl_result,Tcl_NewLongObj(Nout));
04592 Tcl_ListObjAppendElement(interp,tcl_result,Tcl_NewLongObj(nIn));
04593 Tcl_ListObjAppendElement(interp,tcl_result,Tcl_NewLongObj(nVoxIso));
04594 Tcl_SetObjResult(interp,tcl_result);
04595 return TCL_OK;
04596 }
04597
04598 int obj_measure(ClientData cd, Tcl_Interp *interp, int argc,
04599 Tcl_Obj * const objv[]) {
04600
04601 if (argc < 2) {
04602 Tcl_SetResult(interp,
04603 (char *) "usage: measure <command> [args...]\n"
04604 "\nMeasure Commands:\n"
04605 " avpos <sel> [first <first>] [last <last>] [step <step>] -- average position\n"
04606 " center <sel> [weight <weights>] -- geometrical (or weighted) center\n"
04607 " centerperresidue <sel> [weight <weights>] -- geometrical center for every residue in sel\n"
04608 " cluster <sel> [num <#clusters>] [distfunc <flag>] [cutoff <cutoff>]\n"
04609 " [first <first>] [last <last>] [step <step>] [selupdate <bool>]\n"
04610 " [weight <weights>]\n"
04611 " -- perform a cluster analysis (cluster similar timesteps)\n"
04612 " clustsize <sel> [cutoff <float>] [minsize <num>] [numshared <num>]\n"
04613 " [usepbc <bool>] [storesize <fieldname>] [storenum <fieldname>]\n"
04614 " -- perform a cluster size analysis (find clusters of atoms)\n"
04615 " contacts <cutoff> <sel1> [<sel2>] -- list contacts\n"
04616 " dipole <sel> [-elementary|-debye] [-geocenter|-masscenter|-origincenter]\n"
04617 " -- dipole moment\n"
04618 " fit <sel1> <sel2> [weight <weights>] [order <index list>]\n"
04619 " -- transformation matrix from selection 1 to 2\n"
04620 " gofr <sel1> <sel2> [delta <value>] [rmax <value>] [usepbc <bool>]\n"
04621 " [selupdate <bool>] [first <first>] [last <last>] [step <step>]\n"
04622 " -- atomic pair distribution function g(r)\n"
04623 " hbonds <cutoff> <angle> <sel1> [<sel2>]\n"
04624 " -- list donors, acceptors, hydrogens involved in hydrogen bonds\n"
04625 " inverse <matrix> -- inverse matrix\n"
04626 " inertia <sel> [-moments] [-eigenvals] -- COM and principle axes of inertia\n"
04627 " minmax <sel> [-withradii] -- bounding box\n"
04628 " rgyr <sel> [weight <weights>] -- radius of gyration\n"
04629 " rmsd <sel1> <sel2> [weight <weights>] -- RMS deviation\n"
04630 " rmsdperresidue <sel1> <sel2> [weight <weights>] -- deviation per residue\n"
04631 " rmsf <sel> [first <first>] [last <last>] [step <step>] -- RMS fluctuation\n"
04632 " rmsfperresidue <sel> [first <first>] [last <last>] [step <step>] -- fluctuation per residue\n"
04633 " sasa <srad> <sel> [-points <varname>] [-restrict <restrictedsel>]\n"
04634 " [-samples <numsamples>] -- solvent-accessible surface area\n"
04635 " sasaperresidue <srad> <sel> [-points <varname>] [-restrict <restrictedsel>]\n"
04636 " [-samples <numsamples>] -- solvent-accessible surface area per residue\n"
04637 " sumweights <sel> weight <weights> -- sum of selected weights\n"
04638 " bond {{<atomid1> [<molid1>]} {<atomid2> [<molid2>]}}\n"
04639 " [molid <default mol>] [frame <frame|all|last> | first <first> last <last>]\n"
04640 " -- bond length between atoms 1 and 2\n"
04641 " angle {{<atomid1> [<molid1>]} {<atomid2> [<molid2>]} {<atomid3> [<molid3>]}}\n"
04642 " [molid <default mol>] [frame <frame|all|last> | first <first> last <last>]\n"
04643 " -- angle between atoms 1-3\n"
04644 " dihed {{<atomid1> [<molid1>]} ... {<atomid4> [<molid4>]}}\n"
04645 " [molid <default mol>] [frame <frame|all|last> | first <first> last <last>]\n"
04646 " -- dihedral angle between atoms 1-4\n"
04647 " imprp {{<atomid1> [<molid1>]} ... {<atomid4> [<molid4>]}}\n"
04648 " [molid <default mol>] [frame <frame|all|last> | first <first> last <last>]\n"
04649 " -- improper angle between atoms 1-4\n"
04650
04651 " energy bond|angle|dihed|impr|vdw|elec -- compute energy\n"
04652 " surface <sel> <gridsize> <radius> <thickness> -- surface of selection\n"
04653 " pbc2onc <center> [molid <default>] [frame <frame|last>]\n"
04654 " -- transformation matrix to wrap a nonorthogonal PBC unit cell\n"
04655 " into an orthonormal cell\n"
04656 " pbcneighbors <center> <cutoff> [sel <sel>] [align <matrix>] [molid <default>]\n"
04657 " [frame <frame|last>] [boundingbox <PBC|{<mincoord> <maxcoord>}>]\n"
04658 " -- all image atoms that are within cutoff Angstrom of the pbc unit cell\n"
04659 " symmetry <sel> [element [<vector>]] [-tol <value>] [-nobonds] [-verbose <level>]\n"
04660 " transoverlap <sel> <matrix> [-sigma <value>]\n"
04661 " -- overlap of a structure with a transformed copy of itself\n"
04662 " volinterior <sel> [options]\n"
04663 " -- type 'measure volinterior' for usage\n",
04664 TCL_STATIC);
04665 return TCL_ERROR;
04666 }
04667 VMDApp *app = (VMDApp *)cd;
04668 char *argv1 = Tcl_GetStringFromObj(objv[1],NULL);
04669 if (!strupncmp(argv1, "avpos", CMDLEN))
04670 return vmd_measure_avpos(app, argc-1, objv+1, interp);
04671 else if (!strupncmp(argv1, "center", CMDLEN))
04672 return vmd_measure_center(app, argc-1, objv+1, interp);
04673 #if 1
04674
04675 else if (!strupncmp(argv1, "centerperresidue", CMDLEN))
04676 return vmd_measure_centerperresidue(app, argc-1, objv+1, interp);
04677 #endif
04678 else if (!strupncmp(argv1, "cluster", CMDLEN))
04679 return vmd_measure_cluster(app, argc-1, objv+1, interp);
04680 else if (!strupncmp(argv1, "clustsize", CMDLEN))
04681 return vmd_measure_clustsize(app, argc-1, objv+1, interp);
04682 else if (!strupncmp(argv1, "contacts", CMDLEN))
04683 return vmd_measure_contacts(app, argc-1, objv+1, interp);
04684 else if (!strupncmp(argv1, "dipole", CMDLEN))
04685 return vmd_measure_dipole(app, argc-1, objv+1, interp);
04686 else if (!strupncmp(argv1, "fit", CMDLEN))
04687 return vmd_measure_fit(app, argc-1, objv+1, interp);
04688 else if (!strupncmp(argv1, "minmax", CMDLEN))
04689 return vmd_measure_minmax(app, argc-1, objv+1, interp);
04690 else if (!strupncmp(argv1, "gofr", CMDLEN))
04691 return vmd_measure_gofr(app, argc-1, objv+1, interp);
04692 else if (!strupncmp(argv1, "rdf", CMDLEN))
04693 return vmd_measure_rdf(app, argc-1, objv+1, interp);
04694 else if (!strupncmp(argv1, "hbonds", CMDLEN))
04695 return vmd_measure_hbonds(app, argc-1, objv+1, interp);
04696 else if (!strupncmp(argv1, "inverse", CMDLEN))
04697 return vmd_measure_inverse(argc-1, objv+1, interp);
04698 else if (!strupncmp(argv1, "inertia", CMDLEN))
04699 return vmd_measure_inertia(app, argc-1, objv+1, interp);
04700 else if (!strupncmp(argv1, "rgyr", CMDLEN))
04701 return vmd_measure_rgyr(app, argc-1, objv+1, interp);
04702 else if (!strupncmp(argv1, "rmsd", CMDLEN))
04703 return vmd_measure_rmsd(app, argc-1, objv+1, interp);
04704 #if 1
04705
04706 else if (!strupncmp(argv1, "rmsdperresidue", CMDLEN))
04707 return vmd_measure_rmsdperresidue(app, argc-1, objv+1, interp);
04708 #endif
04709 #if 1
04710 else if (!strupncmp(argv1, "rmsd_qcp", CMDLEN))
04711 return vmd_measure_rmsd_qcp(app, argc-1, objv+1, interp);
04712 else if (!strupncmp(argv1, "rmsdmat_qcp", CMDLEN))
04713 return vmd_measure_rmsdmat_qcp(app, argc-1, objv+1, interp);
04714 else if (!strupncmp(argv1, "rmsdmat_qcp_ooc", CMDLEN))
04715 return vmd_measure_rmsdmat_qcp_ooc(app, argc-1, objv+1, interp);
04716 #endif
04717 else if (!strupncmp(argv1, "rmsf", CMDLEN))
04718 return vmd_measure_rmsf(app, argc-1, objv+1, interp);
04719 #if 1
04720
04721 else if (!strupncmp(argv1, "rmsfperresidue", CMDLEN))
04722 return vmd_measure_rmsfperresidue(app, argc-1, objv+1, interp);
04723 #endif
04724 else if (!strupncmp(argv1, "sasa", CMDLEN))
04725 return vmd_measure_sasa(app, argc-1, objv+1, interp);
04726 else if (!strupncmp(argv1, "sasaperresidue", CMDLEN))
04727 return vmd_measure_sasaperresidue(app, argc-1, objv+1, interp);
04728 #if 1
04729 else if (!strupncmp(argv1, "sasalist", CMDLEN))
04730 return vmd_measure_sasalist(app, argc-1, objv+1, interp);
04731 #endif
04732 else if (!strupncmp(argv1, "sumweights", CMDLEN))
04733 return vmd_measure_sumweights(app, argc-1, objv+1, interp);
04734 else if (!strupncmp(argv1, "imprp", CMDLEN))
04735 return vmd_measure_dihed(app, argc-1, objv+1, interp);
04736 else if (!strupncmp(argv1, "dihed", CMDLEN))
04737 return vmd_measure_dihed(app, argc-1, objv+1, interp);
04738 else if (!strupncmp(argv1, "angle", CMDLEN))
04739 return vmd_measure_angle(app, argc-1, objv+1, interp);
04740 else if (!strupncmp(argv1, "bond", CMDLEN))
04741 return vmd_measure_bond(app, argc-1, objv+1, interp);
04742 else if (!strupncmp(argv1, "energy", CMDLEN))
04743 return vmd_measure_energy(app, argc-1, objv+1, interp);
04744 else if (!strupncmp(argv1, "pbc2onc", CMDLEN))
04745 return vmd_measure_pbc2onc_transform(app, argc-1, objv+1, interp);
04746 else if (!strupncmp(argv1, "pbcneighbors", CMDLEN))
04747 return vmd_measure_pbc_neighbors(app, argc-1, objv+1, interp);
04748 else if (!strupncmp(argv1, "surface", CMDLEN))
04749 return vmd_measure_surface(app, argc-1, objv+1, interp);
04750 else if (!strupncmp(argv1, "transoverlap", CMDLEN))
04751 return vmd_measure_trans_overlap(app, argc-1, objv+1, interp);
04752 else if (!strupncmp(argv1, "symmetry", CMDLEN))
04753 return vmd_measure_symmetry(app, argc-1, objv+1, interp);
04754 else if (!strupncmp(argv1, "volinterior", CMDLEN))
04755 return vmd_measure_volinterior(app, argc-1, objv+1, interp);
04756
04757 Tcl_SetResult(interp, (char *) "Type 'measure' for summary of usage\n", TCL_VOLATILE);
04758 return TCL_OK;
04759 }
04760
04761
04762