Last active
May 29, 2020 16:57
-
-
Save ledragna/9f3aa5424aab1b07b33d48df400e4bb6 to your computer and use it in GitHub Desktop.
Small script to cummunicate with jmol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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() | |
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
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
Here I paste the stdout jmol called from python: