Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save fomightez/7692b540ff3c5d817bf5 to your computer and use it in GitHub Desktop.
Save fomightez/7692b540ff3c5d817bf5 to your computer and use it in GitHub Desktop.
Command line piping of a PDB file to Jmol via Python

Command line piping of a PDB file to Jmol via Python

An example

Command to initiate opening of a PDB file in the Jmol desktop application via shell pipes and Python

cat ./jsmol/data/1crn.pdb | python -c "import sys; print 'load DATA \"mydata\"';[sys.stdout.write(line) for line in sys.stdin]; print 'END \"mydata\"\n'" | java -jar Jmol.jar -s -

This example runs in the Jmol directory that is created when it is downloaded and unpacked.
(You'll need to scroll to the right in the command window to see all of it in the posted Gist.)

To exit the app, click in your terminal and type CTRL-c.

It uses Python 2; most computers still have Python 2 installed by default.

The (perhaps boring) detailed conversion process

Converting command line piping of a PDB file to Jmol via PERL like

cat /scratch/pdb/pdb/pdb1deh.ent | perl -ne 'BEGIN { print "load DATA \"mydata\"\n";}  print $_;  END { print "END \"mydata\"\n"; }' | java -jar Jmol.jar -s -

(from Rolf's email on Jmol Users' list dated Date: Fri, 2 Oct 2015 17:12:25 +0200 with subject Re: [Jmol-users] Jmol reads a structure file from a pipe or system input (MPI) )

to using Python 2.7.

See here for how to do multi-line inline Python commands in Bash. Below there is related

python -c "exec(\"import sys\\nfor r in range(10): print 'rob'\")"

and

python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"

and from one-liners here, I found below was especially suitable

python -c "import sys;[sys.stdout.write(' '.join(line.split(' ')[2:])) for line in sys.stdin]" < input.txt

The -s - part of the Jmol java command was explained earlier in the thread where the -s flag means a script will be provided from the command line and the - designating the source as System.in stream. (See other useful command line options here.

This would make the original command using Perl convert to:

cat /scratch/pdb/pdb/pdb1deh.ent | python -c "import sys; print 'load DATA \"mydata\"\n';[sys.stdout.write(line) for line in sys.stdin]; print 'END \"mydata\"\n'" | java -jar Jmol.jar -s -

Note that the brackets are needed because a for command needs to be a block but you cannot put a block after ';' so you can use the brackets trick instead and it will work after ;, see mklement0's comment on Crast's answer

Turns out the \n after print 'load DATA \"mydata\" is unnecessary, but I had originally kept it as a parallel with the Perl code.

In fact this works and is shorter:

cat /scratch/pdb/pdb/pdb1deh.ent | python -c "import sys; print 'load DATA \"mydata\"';[sys.stdout.write(line) for line in sys.stdin]; print 'END \"mydata\"\n'" | java -jar Jmol.jar -s -

or, as in the example,

cat ./jsmol/data/1crn.pdb | python -c "import sys; print 'load DATA \"mydata\"';[sys.stdout.write(line) for line in sys.stdin]; print 'END \"mydata\"\n'" | java -jar Jmol.jar -s -

Unfortunately, I only noted this after posting the command with that extra \n to the Jmol Users's list.

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