00001
00007 #include "InfoStream.h"
00008 #include "Measure.h"
00009 #include "Node.h"
00010 #include "Parameters.h"
00011 #include "Molecule.h"
00012
00013 #ifdef NAMD_TCL
00014
00015 int Measure::wrapCommand(ClientData clientData,
00016 Tcl_Interp *interp, int argc, char *argv[]) {
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 return TCL_OK;
00030 }
00031
00032 static int Tcl_centerOfNumber(ClientData, Tcl_Interp *interp, int argc, char *argv[]) {
00033
00034 Node *node = Node::Object();
00035 Molecule *molecule = node->molecule;
00036
00037 Vector *coordinates = node->coords;
00038 int numAtoms = molecule->numAtoms;
00039
00040 int number = 0;
00041 Vector center = 0;
00042 for( int i = 0; i < numAtoms; ++i ) {
00043 number += 1;
00044 center += coordinates[i];
00045 }
00046 center /= number;
00047
00048 char s[1024];
00049 sprintf(s,"%g %g %g", center.x, center.y, center.z);
00050 Tcl_SetResult(interp,s,TCL_VOLATILE);
00051
00052 return TCL_OK;
00053 }
00054
00055 static int Tcl_centerOfMass(ClientData, Tcl_Interp *interp, int argc, char *argv[]) {
00056
00057 Node *node = Node::Object();
00058 Molecule *molecule = node->molecule;
00059
00060 Vector *coordinates = node->coords;
00061 int numAtoms = molecule->numAtoms;
00062
00063 Vector center = 0;
00064 BigReal totalMass = 0;
00065 for( int i = 0; i < numAtoms; ++i ) {
00066 BigReal mass = molecule->atommass(i);
00067 totalMass += mass;
00068 center += mass * coordinates[i];
00069 }
00070 center /= totalMass;
00071
00072 char s[1024];
00073 sprintf(s,"%g %g %g", center.x, center.y, center.z);
00074 Tcl_SetResult(interp,s,TCL_VOLATILE);
00075
00076 return TCL_OK;
00077 }
00078
00079 static int Tcl_radiusOfGyration(ClientData, Tcl_Interp *interp, int argc, char *argv[]) {
00080
00081 Node *node = Node::Object();
00082 Molecule *molecule = node->molecule;
00083
00084 Vector *coordinates = node->coords;
00085 int numAtoms = molecule->numAtoms;
00086
00087 Vector center = 0;
00088 BigReal totalMass = 0;
00089 int i;
00090 for( i = 0; i < numAtoms; ++i ) {
00091 BigReal mass = molecule->atommass(i);
00092 totalMass += mass;
00093 center += mass * coordinates[i];
00094 }
00095 center /= totalMass;
00096
00097 BigReal moment = 0;
00098 for( i = 0; i < numAtoms; ++i ) {
00099 BigReal mass = molecule->atommass(i);
00100 moment += mass * (coordinates[i] - center).length2();
00101 }
00102 BigReal radius = sqrt(moment/totalMass);
00103
00104 char s[1024];
00105 sprintf(s,"%g", radius);
00106 Tcl_SetResult(interp,s,TCL_VOLATILE);
00107
00108 return TCL_OK;
00109 }
00110
00111 static int Tcl_loadCoords(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) {
00112
00113 if (objc < 2 || objc > 3) {
00114 Tcl_SetResult(interp,"loadCoords: wrong # args",TCL_VOLATILE);
00115 return TCL_ERROR;
00116 }
00117 Tcl_Obj * const vname = objv[1];
00118 Node *node = Node::Object();
00119 Molecule *molecule = node->molecule;
00120
00121 const Vector *coords = node->coords;
00122 int numAtoms = molecule->numAtoms;
00123
00124 if (objc == 2) {
00125
00126 for (int i=0; i<numAtoms; i++) {
00127 Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
00128 Tcl_Obj *arrkey = Tcl_NewIntObj(i+1);
00129 Tcl_IncrRefCount(arrkey);
00130 Tcl_ListObjAppendElement(interp, newlist,
00131 Tcl_NewDoubleObj(coords[i].x));
00132 Tcl_ListObjAppendElement(interp, newlist,
00133 Tcl_NewDoubleObj(coords[i].y));
00134 Tcl_ListObjAppendElement(interp, newlist,
00135 Tcl_NewDoubleObj(coords[i].z));
00136 if (!Tcl_ObjSetVar2(interp, vname, arrkey, newlist, 0))
00137 return TCL_ERROR;
00138 Tcl_DecrRefCount(arrkey);
00139 }
00140 } else {
00141
00142 int nelems;
00143 Tcl_Obj **elems;
00144 if (Tcl_ListObjGetElements(interp, objv[2], &nelems, &elems) != TCL_OK) {
00145 return TCL_ERROR;
00146 }
00147 for (int i=0; i<nelems; i++) {
00148 int ind;
00149 if (Tcl_GetIntFromObj(interp, elems[i], &ind) != TCL_OK)
00150 return TCL_ERROR;
00151 Tcl_Obj *newlist = Tcl_NewListObj(0, NULL);
00152 Tcl_Obj *arrkey = Tcl_NewIntObj(ind);
00153 Tcl_IncrRefCount(arrkey);
00154 --ind;
00155 Tcl_ListObjAppendElement(interp, newlist,
00156 Tcl_NewDoubleObj(coords[ind].x));
00157 Tcl_ListObjAppendElement(interp, newlist,
00158 Tcl_NewDoubleObj(coords[ind].y));
00159 Tcl_ListObjAppendElement(interp, newlist,
00160 Tcl_NewDoubleObj(coords[ind].z));
00161 if (!Tcl_ObjSetVar2(interp, vname, arrkey, newlist, 0))
00162 return TCL_ERROR;
00163 Tcl_DecrRefCount(arrkey);
00164 }
00165 }
00166 return TCL_OK;
00167 }
00168
00169 void Measure::createCommands(Tcl_Interp *interp) {
00170 Tcl_CreateCommand(interp, "centerOfNumber", Tcl_centerOfNumber,
00171 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
00172 Tcl_CreateCommand(interp, "centerOfMass", Tcl_centerOfMass,
00173 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
00174 Tcl_CreateCommand(interp, "radiusOfGyration", Tcl_radiusOfGyration,
00175 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
00176 Tcl_CreateObjCommand(interp, "loadCoords", Tcl_loadCoords,
00177 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
00178 }
00179
00180 void Measure::deleteCommands(Tcl_Interp *interp) {
00181 Tcl_DeleteCommand(interp, "centerOfNumber");
00182 Tcl_DeleteCommand(interp, "centerOfMass");
00183 Tcl_DeleteCommand(interp, "radiusOfGyration");
00184 Tcl_DeleteCommand(interp, "loadCoords");
00185 }
00186
00187 #endif
00188