Skip to content

Instantly share code, notes, and snippets.

@ledragna
Last active May 29, 2020 16:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ledragna/9f3aa5424aab1b07b33d48df400e4bb6 to your computer and use it in GitHub Desktop.
Save ledragna/9f3aa5424aab1b07b33d48df400e4bb6 to your computer and use it in GitHub Desktop.
Small script to cummunicate with jmol
#! /usr/bin/env python -u
import sys
import os
import socket
import json
from string import Template
from subprocess import Popen, PIPE
from time import sleep
DEBUG = True
class JmolWrapper():
def __init__(self, host='127.0.0.1', port=8008):
self.host = host
self.port = port
pwd = os.getcwd()
self.jmol = Popen(['jmol -o -j "sync -8008"'], shell=True,
stdin=PIPE,
#stdin=PIPE,
universal_newlines=True,
bufsize=1,
stdout=PIPE, stderr=PIPE)
self.cnct = False
# wait for socket initialization
sleep(1)
def _connect(self):
retrives = 5 # numbers of attempts
while not self.cnct and retrives > 0:
data = None
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((self.host, self.port))
cmd_ ='{"magic":"JmolApp","role":"out"}\r\n'
self.sock.send(cmd_.encode('UTF-8'))
rpl = json.loads(self.sock.recv(1024).decode('UTF-8'))
print('Connection:{:5s}'.format(rpl['reply']))
if rpl['reply'] == 'OK':
self.cnct = True
except ConnectionRefusedError:
sleep(0.4)
retrives -= 1
if retrives < 1:
print('Unable to connect')
return data
def close(self):
"""
Close Jmol
"""
cmd_ ='{"type": "command", "command": "exitJmol"}\r\n'
self.sock.send(cmd_.encode('UTF-8'))
rpl = self.sock.recv(1024).decode('UTF-8')
rpl = [json.loads(x) for x in rpl.split('\n') if x]
if DEBUG:
print(rpl)
self.sock.close()
def send_cmd(self, cmmnd):
"""
cmmnd: jmol scripting command
"""
if not self.cnct:
self._connect()
tmp = Template('{"type": "command", "command": "$command"}\r\n')
cmd_ = tmp.substitute(command=cmmnd)
self.sock.send(cmd_.encode('UTF-8'))
rsp = []
while True:
rpl = self.sock.recv(1024).decode('UTF-8')
try:
rpl_ = [json.loads(x) for x in rpl.split('\n') if x]
except json.decoder.JSONDecodeError:
rpl_ = 'Missing'
rsp.extend(rpl_)
if "SCRIPT:Jmol script terminated" in rsp[-1]['reply']:
break
if DEBUG:
print(rsp)
# TODO check the output
#return data
def openfile(self, fname):
"""
Open a file
"""
tmpl = 'load FILES {}'
try:
os.stat(fname)
self.send_cmd(tmpl.format(fname))
except FileNotFoundError:
print('File not found')
def test():
"""
Example
"""
try:
jmol = JmolWrapper()
except FileNotFoundError:
print('Jmol not installed')
sys.exit()
# Opens the molecule
msg = 'load $C1CCCCC1'
jmol.send_cmd(msg)
#selects the hydrogen and turns on halo
msg = 'select _H; halo on; rotate'
jmol.send_cmd(msg)
# waits 10 second
sleep(10)
# close jmol
jmol.close()
if DEBUG:
stdoutlog = jmol.jmol.stdout.readlines()
with open('stdout_log.log', 'w') as fopen:
for line in stdoutlog:
fopen.write(line)
if __name__ == "__main__":
test()
@ledragna
Copy link
Author

Here I paste the stdout jmol called from python:

425 translations loaded
544 translations loaded
splash_image=jar:file:/usr/share/jmol/Jmol.jar!/org/openscience/jmol/app/images/Jmol_splash.jpg
(C) 2015 Jmol Development
Jmol Version: 14.30.2  2019-11-26 10:18
java.vendor: Java: Oracle Corporation
java.version: Java 1.8.0_242
os.name: Linux
Access: ALL
memory: 34.7/187.2
processors available: 4
useCommandThread: false
User macros dir: /home/marco/.jmol/macros
       exists: false
  isDirectory: false
appConsole Linux
Executing script from file: -
OK -- JSONNIOSERVICE
JsonNIOService setEnabled contentdisabled=false motionDisabled=false
NIOcontentPath=
NIOterminatorMessage=
NIOresetMessage=
NIOcontentDisabled=false
NIOmotionDisabled=false
JsonNioService-1 using port 8008
JsonNiosThread-1 JsonNioSocket on 8008
JsonNiosThread-1 inSocket connectionBroken
JsonNiosThread-1 outSocket connectionBroken
JsonNioService-1 close
JsonNioServerThread-1 JsonNioServerSocket on 8008
JsonNioServerThread-1 Received connection: Socket[addr=/127.0.0.1,port=59834,localport=8008]
JsonNioService msg={"type": "command", "command": "load $C1CCCCC1"}
JsonNioService json={"type":Token[string(4/0x4) value="command"][null index =2147483647 intValue=2147483647],"command":Token[string(4/0x4) value="load $C1CCCCC1"][null index =2147483647 intValue=2147483647]}
JsonNioService processJSON msg={"type": "command", "command": "load $C1CCCCC1"}
 type=command
OK -- JSONNIOSERVICE
JsonNIOService setEnabled contentdisabled=false motionDisabled=false
JsonNiosService sendScript load $C1CCCCC1

FileManager.getAtomSetCollectionFromFile(https://cactus.nci.nih.gov/chemical/structure/C1CCCCC1/file?format=sdf&get3d=true)
FileManager opening url https://cactus.nci.nih.gov/chemical/structure/C1CCCCC1/file?format=sdf&get3d=true
The Resolver thinks Mol
C6H12
APtclcactv05252017493D 0   0.00000     0.00000


C6H12
Time for openFile(https://cactus.nci.nih.gov/chemical/structure/C1CCCCC1/file?format=sdf&get3d=true): 1264 ms
reading 18 atoms
ModelSet: haveSymmetry:false haveUnitcells:false haveFractionalCoord:false
1 model in this collection. Use getProperty "modelInfo" or getProperty "auxiliaryInfo" to inspect them.
Default Van der Waals type for model set to Babel
18 atoms created
ModelSet: not autobonding; use  forceAutobond=true  to force automatic bond creation
Time for creating model: 11 ms
C6H12

@ledragna
Copy link
Author

and this is the same operation made with a jmol to jmol interaction:

425 translations loaded
544 translations loaded
splash_image=jar:file:/usr/share/jmol/Jmol.jar!/org/openscience/jmol/app/images/Jmol_splash.jpg
(C) 2015 Jmol Development
Jmol Version: 14.30.2  2019-11-26 10:18
java.vendor: Java: Oracle Corporation
java.version: Java 1.8.0_242
os.name: Linux
Access: ALL
memory: 34.8/187.2
processors available: 4
useCommandThread: false
User macros dir: /home/marco/.jmol/macros
       exists: false
  isDirectory: false
appConsole Linux
JsonNioServerThread-1 JsonNioServerSocket on 8007
JsonNioServerThread-1 Received connection: Socket[addr=/127.0.0.1,port=49528,localport=8007]
JsonNioServerThread-1 Received connection: Socket[addr=/127.0.0.1,port=49530,localport=8007]
JsonNioService msg={"magic":"JmolApp","role":"out"}
JsonNioService json={"magic":Token[string(4/0x4) value="JmolApp"][null index =2147483647 intValue=2147483647],"role":Token[string(4/0x4) value="out"][null index =2147483647 intValue=2147483647]}
JsonNioService msg={"type": "command", "command": "load $C1CCCCC1"}
JsonNioService json={"type":Token[string(4/0x4) value="command"][null index =2147483647 intValue=2147483647],"command":Token[string(4/0x4) value="load $C1CCCCC1"][null index =2147483647 intValue=2147483647]}
JsonNioService processJSON msg={"type": "command", "command": "load $C1CCCCC1"} type=command
OK -- JSONNIOSERVICE
JsonNIOService setEnabled contentdisabled=false motionDisabled=false
JsonNiosService sendScript load $C1CCCCC1
JsonNioService msg={"magic":"JmolApp","role":"in"}
JsonNioService json={"magic":Token[string(4/0x4) value="JmolApp"][null index =2147483647 intValue=2147483647],"role":Token[string(4/0x4) value="in"][null index =2147483647 intValue=2147483647]}

FileManager.getAtomSetCollectionFromFile(https://cactus.nci.nih.gov/chemical/structure/C1CCCCC1/file?format=sdf&get3d=true)
FileManager opening url https://cactus.nci.nih.gov/chemical/structure/C1CCCCC1/file?format=sdf&get3d=true
The Resolver thinks Mol
C6H12
APtclcactv05252017493D 0   0.00000     0.00000


C6H12
Time for openFile(https://cactus.nci.nih.gov/chemical/structure/C1CCCCC1/file?format=sdf&get3d=true): 1136 ms
reading 18 atoms
ModelSet: haveSymmetry:false haveUnitcells:false haveFractionalCoord:false
1 model in this collection. Use getProperty "modelInfo" or getProperty "auxiliaryInfo" to inspect them.
Default Van der Waals type for model set to Babel
18 atoms created
ModelSet: not autobonding; use  forceAutobond=true  to force automatic bond creation
Time for creating model: 17 ms
C6H12

@ledragna
Copy link
Author

ledragna commented May 29, 2020

 def send_cmd(self, cmmnd):
        """
        cmmnd: jmol scripting command
        """
        if not self.cnct:
            self._connect()
        tmp = Template('{"type": "command", "command": "$command"}\r\n')
        cmd_ = tmp.substitute(command=cmmnd)
        self.sock.send(cmd_.encode('UTF-8'))
        rsp = []
        while True:
            rpl = self.sock.recv(1024).decode('UTF-8')
            try:
                rpl_ = [json.loads(x) for x in rpl.split('\n') if x]
            except json.decoder.JSONDecodeError:
                rpl_ = 'Missing'
            rsp.extend(rpl_)
            if "SCRIPT:Jmol script terminated" in rsp[-1]['reply']:
                    break
        print(rsp)
        # TODO check the output
        #return data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment