File: vmd.py

package info (click to toggle)
lammps 20250204%2Bdfsg.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 474,368 kB
  • sloc: cpp: 1,060,070; python: 27,785; ansic: 8,956; f90: 7,254; sh: 6,044; perl: 4,171; fortran: 2,442; xml: 1,714; makefile: 1,352; objc: 238; lisp: 188; yacc: 58; csh: 16; awk: 14; tcl: 6; javascript: 2
file content (225 lines) | stat: -rw-r--r-- 8,967 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# Pizza.py toolkit, https://lammps.github.io/pizza
# LAMMPS Development team: developers@lammps.org, Sandia National Laboratories
#
# Copyright (2005) Sandia Corporation.  Under the terms of Contract
# DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
# certain rights in this software.  This software is distributed under
# the GNU General Public License.

# for python3 compatibility
from __future__ import print_function

# vmd tool

# Minimalistic VMD embedding for Pizza.py
# (c) 2010 Axel Kohlmeyer <akohlmey@gmail.com>
# This class will replace the VMD startup script,
#   open a pipe to the executable,
#   and feed it Tcl command lines one at a time

oneline = "Control VMD from python"

docstr = """
v = vmd()                      start up VMD
v.stop()                       shut down VMD instance
v.clear()                      delete all visualizations

v.rep(style)                   set default representation style. One of
                               (Lines|VDW|Licorice|DynamicBonds|Points|CPK)
v.new(file[,type])             load new file (default file type 'lammpstrj')
v.data(file[,atomstyle])       load new data file (default atom style 'full')
v.replace(file[,type])         replace current frames with new file
v.append(file[,type])          append file to current frame(s)
v.set(snap,x,y,z,(True|False)) set coordinates from a pizza.py snapshot to new or current frame

v.frame(frame)                 set current frame
v.flush()                      flush pending input to VMD and update GUI
v.read(file)                   read Tcl script file (e.g. saved state)

v.enter()                      enter interactive shell
v.debug([True|False])          display generated VMD script commands?
"""

# History
#   11/10, Axel Kohlmeyer (Temple U): original version

# Imports and external programs

import os

try: from DEFAULTS import PIZZA_VMDNAME
except ImportError: PIZZA_VMDNAME = "vmd"
try: from DEFAULTS import PIZZA_VMDDIR
except ImportError: PIZZA_VMDDIR = "/usr/local/lib/vmd"
try: from DEFAULTS import PIZZA_VMDDEV
except ImportError: PIZZA_VMDDEV = "win"
try: from DEFAULTS import PIZZA_VMDARCH
except ImportError: PIZZA_VMDARCH = "LINUXAMD64"

# try these settings for a Mac
#PIZZA_VMDNAME = "vmd"
#PIZZA_VMDDIR = "/Applications/VMD\ 1.8.7.app/Contents/vmd"
#PIZZA_VMDDEV = "win"
#PIZZA_VMDARCH = "MACOSXX86"

try: import pexpect
except ImportError:
  print("pexpect from http://pypi.python.org/pypi/pexpect", \
      "is required for vmd tool")
  raise

# Class definition

class vmd:

  # --------------------------------------------------------------------

  def __init__(self):
    self.vmddir = PIZZA_VMDDIR
    self.vmdexe = PIZZA_VMDDIR + '/' + PIZZA_VMDNAME + '_' + PIZZA_VMDARCH
    # these are all defaults copied from the vmd launch script
    os.environ['VMDDIR'] = PIZZA_VMDDIR
    os.environ['VMDDISPLAYDEVICE'] = PIZZA_VMDDEV
    os.environ['VMDSCRPOS']    = "596 190"
    os.environ['VMDSCRSIZE']   = "669 834"
    os.environ['VMDSCRHEIGHT'] = "6.0"
    os.environ['VMDSCRDIST']   = "-2.0"
    os.environ['VMDTITLE']     = "on"
    os.environ['TCL_LIBRARY'] = PIZZA_VMDDIR + "/scripts/tcl"
    os.environ['STRIDE_BIN']  = PIZZA_VMDDIR + "/stride_" + PIZZA_VMDARCH
    os.environ['SURF_BIN']    = PIZZA_VMDDIR + "/surf_" + PIZZA_VMDARCH
    os.environ['TACHYON_BIN'] = PIZZA_VMDDIR + "/tachyon_" + PIZZA_VMDARCH
    ldpath = os.environ.get('LD_LIBRARY_PATH','')
    if ldpath == '':
      os.environ['LD_LIBRARY_PATH'] = PIZZA_VMDDIR
    else:
      os.environ['LD_LIBRARY_PATH'] = ldpath + ':' + PIZZA_VMDDIR
    ldpath = os.environ.get('LD_LIBRARY_PATH','')
    if ldpath == '':
      os.environ['PYTHONPATH'] = PIZZA_VMDDIR
    else:
      os.environ['PYTHONPATH'] = PIZZA_VMDDIR + "/scripts/python"
    self.debugme = False
    # open pipe to vmd and wait until we have a prompt
    self.VMD = pexpect.spawn(self.vmdexe)
    self.VMD.expect('vmd >')

  # --------------------------------------------------------------------
  # post command to vmd and wait until the prompt returns.
  def __call__(self,command):
    if self.VMD.isalive():
      self.VMD.sendline(command)
      self.VMD.expect('vmd >')
      if self.debugme:
        print("call+result:"+self.VMD.before)
    return

  # --------------------------------------------------------------------
  # exit VMD
  def stop(self):
    self.__call__("quit")
    del self.VMD

  # --------------------------------------------------------------------
  # force VMD display and GUI update.
  def flush(self):
    self.__call__('display update ui')

  # --------------------------------------------------------------------
  # turn on debugging info
  def debug(self,status=True):
    if status and not self.debugme:
      print('Turning vmd.py debugging ON.')
    if not status and self.debugme:
      print('Turning vmd.py debugging OFF.')
    self.debugme = status

  # --------------------------------------------------------------------
  # emulate a regular tcl command prompt
  def enter(self,mode='tcl'):
    self.__call__('menu main off')
    self.__call__('menu main on')
    while 1:
      try:
        command = raw_input("vmd > ")
      except EOFError:
        print("(EOF)")
        self.__call__('menu main off')
        return
      if command == "quit" or command == "exit":
        self.__call__('menu main off')
        return
      if command == "gopython":
        print("gopython not supported here")
        continue
      self.__call__(command)

  # --------------------------------------------------------------------
  # read and execute tcl script file (e.g. a saved state)
  def read(self,filename):
    self.__call__('play ' + filename)
    self.flush()

  # --------------------------------------------------------------------
  # remove all molecules, data and visualizations
  def clear(self):
    self.__call__("mol delete all")

  # --------------------------------------------------------------------
  # navigate to a given frame
  def rep(self,style='Lines'):
    if style == 'Lines' or style == 'VDW' or style == 'Licorice' \
       or style == 'DynamicBonds' or style == 'Points' or style == 'CPK':
      self.__call__('mol default style ' + style)
  # --------------------------------------------------------------------
  # navigate to a given frame
  def frame(self,framespec):
    self.__call__('animate goto ' + str(framespec))

  # --------------------------------------------------------------------
  # load a new molecule from a file supported by a molfile plugin
  def new(self,filename,filetype='lammpstrj'):
    self.__call__('mol new ' + filename + ' type ' + filetype + ' waitfor all')
    self.flush()

  # --------------------------------------------------------------------
  # load a new molecule from a data file via the topotools plugin
  def data(self,filename,atomstyle='full'):
    self.__call__('package require topotools 1.0')
    self.__call__('topo readlammpsdata ' + filename + ' ' + atomstyle)
    self.flush()

  # --------------------------------------------------------------------
  # append all frames from a given file to the current molecule
  def append(self,filename,filetype='lammpstrj'):
    self.__call__('set tmol [molinfo top]')
    self.__call__('array set viewpoints {}')
    self.__call__('foreach mol [molinfo list] { set viewpoints($mol) [molinfo $mol get { center_matrix rotate_matrix scale_matrix global_matrix}]}')
    self.__call__('mol addfile ' + filename + ' mol $tmol type ' + filetype + ' waitfor all')
    self.__call__('foreach mol [molinfo list] { molinfo $mol set {center_matrix rotate_matrix scale_matrix global_matrix} $viewpoints($mol)}')
    self.flush()

  # --------------------------------------------------------------------
  # replace all frames of a molecule with those from a given file
  def update(self,filename,filetype='lammpstrj'):
    self.__call__('set tmol [molinfo top]')
    self.__call__('array set viewpoints {}')
    self.__call__('foreach mol [molinfo list] {set viewpoints($mol) [molinfo $mol get { center_matrix rotate_matrix scale_matrix global_matrix}]}')
    self.__call__('animate delete all $tmol')
    self.__call__('mol addfile ' + filename + ' mol $tmol type ' + filetype + ' waitfor all')
    self.__call__('foreach mol [molinfo list] {molinfo $mol set {center_matrix rotate_matrix scale_matrix global_matrix} $viewpoints($mol)}')
    self.flush()

  # --------------------------------------------------------------------
  # add or overwrite coordinates with coordinates in a snapshot
  def set(self,snap,x,y,z,append=True):
    self.__call__('set vmdsel [atomselect top all]')
    if append:
      self.__call__('animate dup [molinfo top]')
    cmd = '$vmdsel set {x y z} {'
    for idx in range(0,snap.natoms):
      cmd += ' {'+str(snap[idx,x])+' '+str(snap[idx,y])+' '+str(snap[idx,z])+'}'
    cmd += '}'
    self.__call__(cmd)
    self.__call__('$vmdsel delete ; unset vmdsel')
    self.flush()