1# Pizza.py toolkit, www.cs.sandia.gov/~sjplimp/pizza.html 2# Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories 3# 4# Copyright (2005) Sandia Corporation. Under the terms of Contract 5# DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains 6# certain rights in this software. This software is distributed under 7# the GNU General Public License. 8 9# vmd tool 10 11# Minimalistic VMD embedding for Pizza.py 12# (c) 2010 Axel Kohlmeyer <akohlmey@gmail.com> 13# This class will replace the VMD startup script, 14# open a pipe to the executable, 15# and feed it Tcl command lines one at a time 16 17oneline = "Control VMD from python" 18 19docstr = """ 20v = vmd() start up VMD 21v.stop() shut down VMD instance 22v.clear() delete all visualizations 23 24v.rep(style) set default representation style. One of 25 (Lines|VDW|Licorice|DynamicBonds|Points|CPK) 26v.new(file[,type]) load new file (default file type 'liggghtstrj') 27v.data(file[,atomstyle]) load new data file (default atom style 'full') 28v.replace(file[,type]) replace current frames with new file 29v.append(file[,type]) append file to current frame(s) 30v.set(snap,x,y,z,(True|False)) set coordinates from a pizza.py snapshot to new or current frame 31 32v.frame(frame) set current frame 33v.flush() flush pending input to VMD and update GUI 34v.read(file) read Tcl script file (e.g. saved state) 35 36v.enter() enter interactive shell 37v.debug([True|False]) display generated VMD script commands? 38""" 39 40# History 41# 11/10, Axel Kohlmeyer (Temple U): original version 42 43# Imports and external programs 44 45import types, os 46import numpy 47 48try: from DEFAULTS import PIZZA_VMDNAME 49except: PIZZA_VMDNAME = "vmd" 50try: from DEFAULTS import PIZZA_VMDDIR 51except: PIZZA_VMDDIR = "/usr/local/lib/vmd" 52try: from DEFAULTS import PIZZA_VMDDEV 53except: PIZZA_VMDDEV = "win" 54try: from DEFAULTS import PIZZA_VMDARCH 55except: PIZZA_VMDARCH = "LINUX" 56 57# try these settings for a Mac 58#PIZZA_VMDNAME = "vmd" 59#PIZZA_VMDDIR = "/Applications/VMD\ 1.8.7.app/Contents/vmd" 60#PIZZA_VMDDEV = "win" 61#PIZZA_VMDARCH = "MACOSXX86" 62 63try: import pexpect 64except: 65 print "pexpect from http://pypi.python.org/pypi/pexpect", \ 66 "is required for vmd tool" 67 raise 68 69# Class definition 70 71class vmd: 72 73 # -------------------------------------------------------------------- 74 75 def __init__(self): 76 self.vmddir = PIZZA_VMDDIR 77 self.vmdexe = PIZZA_VMDDIR + '/' + PIZZA_VMDNAME + '_' + PIZZA_VMDARCH 78 # these are all defaults copied from the vmd launch script 79 os.environ['VMDDIR'] = PIZZA_VMDDIR 80 os.environ['VMDDISPLAYDEVICE'] = PIZZA_VMDDEV 81 os.environ['VMDSCRPOS'] = "596 190" 82 os.environ['VMDSCRSIZE'] = "669 834" 83 os.environ['VMDSCRHEIGHT'] = "6.0" 84 os.environ['VMDSCRDIST'] = "-2.0" 85 os.environ['VMDTITLE'] = "on" 86 os.environ['TCL_LIBRARY'] = PIZZA_VMDDIR + "/scripts/tcl" 87 os.environ['STRIDE_BIN'] = PIZZA_VMDDIR + "/stride_" + PIZZA_VMDARCH 88 os.environ['SURF_BIN'] = PIZZA_VMDDIR + "/surf_" + PIZZA_VMDARCH 89 os.environ['TACHYON_BIN'] = PIZZA_VMDDIR + "/tachyon_" + PIZZA_VMDARCH 90 ldpath = os.environ.get('LD_LIBRARY_PATH','') 91 if ldpath == '': 92 os.environ['LD_LIBRARY_PATH'] = PIZZA_VMDDIR 93 else: 94 os.environ['LD_LIBRARY_PATH'] = ldpath + ':' + PIZZA_VMDDIR 95 ldpath = os.environ.get('LD_LIBRARY_PATH','') 96 if ldpath == '': 97 os.environ['PYTHONPATH'] = PIZZA_VMDDIR 98 else: 99 os.environ['PYTHONPATH'] = PIZZA_VMDDIR + "/scripts/python" 100 self.debugme = False 101 # open pipe to vmd and wait until we have a prompt 102 self.VMD = pexpect.spawn(self.vmdexe) 103 self.VMD.expect('vmd >') 104 105 # -------------------------------------------------------------------- 106 # post command to vmd and wait until the prompt returns. 107 def __call__(self,command): 108 if self.VMD.isalive(): 109 self.VMD.sendline(command) 110 self.VMD.expect('vmd >') 111 if self.debugme: 112 print "call+result:"+self.VMD.before 113 return 114 115 # -------------------------------------------------------------------- 116 # exit VMD 117 def stop(self): 118 self.__call__("quit") 119 del self.VMD 120 121 # -------------------------------------------------------------------- 122 # force VMD display and GUI update. 123 def flush(self): 124 self.__call__('display update ui') 125 126 # -------------------------------------------------------------------- 127 # turn on debugging info 128 def debug(self,status=True): 129 if status and not self.debugme: 130 print 'Turning vmd.py debugging ON.' 131 if not status and self.debugme: 132 print 'Turning vmd.py debugging OFF.' 133 self.debugme = status 134 135 # -------------------------------------------------------------------- 136 # emulate a regular tcl command prompt 137 def enter(self,mode='tcl'): 138 self.__call__('menu main off') 139 self.__call__('menu main on') 140 while 1: 141 try: 142 command = raw_input("vmd > ") 143 except EOFError: 144 print "(EOF)" 145 self.__call__('menu main off') 146 return 147 if command == "quit" or command == "exit": 148 self.__call__('menu main off') 149 return 150 if command == "gopython": 151 print "gopython not supported here" 152 continue 153 self.__call__(command) 154 155 # -------------------------------------------------------------------- 156 # read and execute tcl script file (e.g. a saved state) 157 def read(self,filename): 158 self.__call__('play ' + filename) 159 self.flush() 160 161 # -------------------------------------------------------------------- 162 # remove all molecules, data and visualizations 163 def clear(self): 164 self.__call__("mol delete all") 165 166 # -------------------------------------------------------------------- 167 # navigate to a given frame 168 def rep(self,style='Lines'): 169 if style == 'Lines' or style == 'VDW' or style == 'Licorice' \ 170 or style == 'DynamicBonds' or style == 'Points' or style == 'CPK': 171 self.__call__('mol default style ' + style) 172 # -------------------------------------------------------------------- 173 # navigate to a given frame 174 def frame(self,framespec): 175 self.__call__('animate goto ' + str(framespec)) 176 177 # -------------------------------------------------------------------- 178 # load a new molecule from a file supported by a molfile plugin 179 def new(self,filename,filetype='liggghtstrj'): 180 self.__call__('mol new ' + filename + ' type ' + filetype + ' waitfor all') 181 self.flush() 182 183 # -------------------------------------------------------------------- 184 # load a new molecule from a data file via the topotools plugin 185 def data(self,filename,atomstyle='full'): 186 self.__call__('package require topotools 1.0') 187 self.__call__('topo readliggghtsdata ' + filename + ' ' + atomstyle) 188 self.flush() 189 190 # -------------------------------------------------------------------- 191 # append all frames from a given file to the current molecule 192 def append(self,filename,filetype='liggghtstrj'): 193 self.__call__('set tmol [molinfo top]') 194 self.__call__('array set viewpoints {}') 195 self.__call__('foreach mol [molinfo list] { set viewpoints($mol) [molinfo $mol get { center_matrix rotate_matrix scale_matrix global_matrix}]}') 196 self.__call__('mol addfile ' + filename + ' mol $tmol type ' + filetype + ' waitfor all') 197 self.__call__('foreach mol [molinfo list] { molinfo $mol set {center_matrix rotate_matrix scale_matrix global_matrix} $viewpoints($mol)}') 198 self.flush() 199 200 # -------------------------------------------------------------------- 201 # replace all frames of a molecule with those from a given file 202 def update(self,filename,filetype='liggghtstrj'): 203 self.__call__('set tmol [molinfo top]') 204 self.__call__('array set viewpoints {}') 205 self.__call__('foreach mol [molinfo list] {set viewpoints($mol) [molinfo $mol get { center_matrix rotate_matrix scale_matrix global_matrix}]}') 206 self.__call__('animate delete all $tmol') 207 self.__call__('mol addfile ' + filename + ' mol $tmol type ' + filetype + ' waitfor all') 208 self.__call__('foreach mol [molinfo list] {molinfo $mol set {center_matrix rotate_matrix scale_matrix global_matrix} $viewpoints($mol)}') 209 self.flush() 210 211 # -------------------------------------------------------------------- 212 # add or overwrite coordinates with coordinates in a snapshot 213 def set(self,snap,x,y,z,append=True): 214 self.__call__('set vmdsel [atomselect top all]') 215 if append: 216 self.__call__('animate dup [molinfo top]') 217 cmd = '$vmdsel set {x y z} {' 218 for idx in range(0,snap.natoms): 219 cmd += ' {'+str(snap[idx,x])+' '+str(snap[idx,y])+' '+str(snap[idx,z])+'}' 220 cmd += '}' 221 self.__call__(cmd) 222 self.__call__('$vmdsel delete ; unset vmdsel') 223 self.flush() 224