11 October 2013

518. Generating enantiomers of molecular structures given in XYZ coordinates using python.

What I'm showing here is probably overkill -- there may be better ways of doing this with sed/awk*. However, since I had most of the code below ready as it was part of another script, doing this is python was quick and easy. Plus it's portable-ish.

*[ECCE, which I use for managing my calculations, is very, very particular about the format of the XYZ file, including the number of chars between coordinates. So simply doing e.g.

cat molecule.xyz|gawk '{print $1,$2,$3,-$4}'

won't work. Not all pieces of software are that picky when it comes to xyz coordinates though -- jmol, for example, is very forgiving.]

Anyway, the script below flips a molecular structure by taking the geometry given as a (properly formatted) XYZ file, and changing the sign in front of the Z coordinates. It's that simple.
Save it, call it flip_xyz, make it executable and call it using e.g.

flip_xyz molecule.xyz flipped_molecule.xyz

Script:
#!/usr/bin/python
import sys 

def getrawdata(infile):
    f=open(infile,'r')
    n=0 
    preamble=[]
    struct=[]
  
    for line in f:
        if n<2: data-blogger-escaped-if="" data-blogger-escaped-line.rstrip="" data-blogger-escaped-n="" data-blogger-escaped-preamble="">1:
            line=line.rstrip()
            struct+=[line]
        n+=1
    xyz=[struct]
    
    return xyz, preamble

def genxyzstring(coords,elementnumber):
    x_str='%10.5f'% coords[0]
    y_str='%10.5f'% coords[1]
    z_str='%10.5f'% -coords[2]
    element=elementnumber
    xyz_string=element+(3-len(element))*' '+10*' '+\ 
    (8-len(x_str))*' '+x_str+10*' '+(8-len(y_str))*' '+y_str+10*' '+(8-len(z_str))*' '+z_str+'\n'
    
    return xyz_string

def getstructures(rawdata,preamble,outfile):
    n=0 
    for structure in rawdata:
        n=n+1
        num="%03d" % (n,)
        g=open(outfile,'w')
        cartesian=[]
    
        for item in structure:
            coordx=filter(None,item.split(' ')) 
            coordy=filter(None,item.split('\t'))
            if len(coordx)>len(coordy):
                coords=coordx
            else:
                coords=coordy
    
            coordinates=[float(coords[1]),float(coords[2]),float(coords[3])]
            element=coords[0]
            cartesian+=[genxyzstring(coordinates,element)]
    
        g.write(str(preamble[0])+'\n')
        g.write(str(preamble[1])+'\n')
        for line in cartesian:
            g.write(line)
        g.close()
        cartesian=[]
    return 0

if __name__ == "__main__":
    infile=sys.argv[1]
    outfile=sys.argv[2]
    xyz,preamble=getrawdata(infile)
    structures=getstructures(xyz,preamble,outfile)


20 September 2013

517. Very briefly: Prime95 (GIMPS) on linux

I'm very unhappy about a newly built node which randomly crashes and reboots when running long jobs. More about that later, but here are the specs: FX 8350, 4x8 Gb RAM GSkill Ripjaws, ASRock FX990 Extreme3, Corsair GS700, MSI N210, ASUS NX1101 in an Antec GX700 case, running Wheezy with stock kernel (3.2.0-4 amd64).

I've tested the RAM using memtest86+  and found no errors, the rig uses a 700 W Corsair PSU which /should/ provide enough power, and I see no evidence of overheating based on a cronjob which runs every 2 minutes. Anyway, the first step in troubleshooting is finding a good way of reproducing the error reliably, and prime95 is what the windows overclockers use to stresstest.

Turns out prime95 (actually GIMPS) can run in a few different modes which tests different aspects of you system, which makes it sound like a pretty good program for my purposes.

See here for more information: http://www.mersenne.org/freesoft/

mkdir ~/tmp/mprime -p
cd ~/tmp/mprime
wget http://www.mersenne.info/gimps/p95v279.linux64.tar.gz
tar xvf p95v279.linux64.tar.gz
./mprime
Welcome to GIMPS, the hunt for huge prime numbers. You will be asked a few simple questions and then the program will contact the primenet server to get some work for your computer. Good luck! Attention OVERCLOCKERS!! Mprime has gained a reputation as a useful stress testing tool for people that enjoy pushing their hardware to the limit. You are more than welcome to use this software for that purpose. Please select the stress testing choice below to avoid interfering with the PrimeNet server. Use the Options/Torture Test menu choice for your stress tests. Also, read the stress.txt file. If you want to both join GIMPS and run stress tests, then Join GIMPS and answer the questions. After the server gets some work for you, stop mprime, then run mprime -m and choose Options/Torture Test. Join Gimps? (Y=Yes, N=Just stress testing) (Y): N Number of torture test threads to run (3): 2 Choose a type of torture test to run. 1 = Small FFTs (maximum FPU stress, data fits in L2 cache, RAM not tested much). 2 = In-place large FFTs (maximum heat and power consumption, some RAM tested). 3 = Blend (tests some of everything, lots of RAM tested). 11,12,13 = Allows you to fine tune the above three selections. Blend is the default. NOTE: if you fail the blend test, but can pass the small FFT test then your problem is likely bad memory or a bad memory controller. Type of torture test to run (3): 1 Accept the answers above? (Y): Y [Main thread Sep 20 11:06] Starting workers. [Worker #1 Sep 20 11:06] Worker starting [Worker #1 Sep 20 11:06] Setting affinity to run worker on any logical CPU. [Worker #2 Sep 20 11:06] Worker starting [Worker #2 Sep 20 11:06] Setting affinity to run worker on any logical CPU. [Worker #1 Sep 20 11:06] Beginning a continuous self-test to check your computer. [Worker #1 Sep 20 11:06] Please read stress.txt. Hit ^C to end this test. [Worker #2 Sep 20 11:06] Beginning a continuous self-test to check your computer. [Worker #2 Sep 20 11:06] Please read stress.txt. Hit ^C to end this test. [Worker #1 Sep 20 11:06] Test 1, 180000 Lucas-Lehmer iterations of M580673 using AMD K10 type-1 FFT length 28K, Pass1=112, Pass2=256. [Worker #2 Sep 20 11:06] Test 1, 180000 Lucas-Lehmer iterations of M580673 using AMD K10 type-1 FFT length 28K, Pass1=112, Pass2=256. CTRL+C
And so on.

19 September 2013

516. Potential energy diagrammes in latex using pgfplots

Given these recent posts, a post on how to represent reaction coordinates in latex was inevitable.

Note: a much prettier example is found here: https://quantumchemistryniser.wordpress.com/2013/05/25/potential-energy-profile-using-pgfplots/

However, I initially couldn't reproduce it, and after spending a few hours with pgfplots I wanted my own style anyway.


But first, a recap:
Once you've completely left office-like wordprocessors behinds and fully embraced the wonder of typesetting in LaTeX you find yourself wanting to produce more and more of the figures directly in latex, rather than simply importing figures.

While nothing beats gnuplot for plotting, and pov-ray (via e.g. gdis) for fancy figures and bkchem for simple 2d structures, there are some nice and simple latex packages that make life easier: I touch on a few in this post: http://verahill.blogspot.com.au/2012/07/debian-texlive-and-style-files-making.html

For chemical formulae, use mhchem -- I think it's standard in debian for texlive. It's indispensable. Also see http://www.ctan.org/pkg/mhchem

For very, very simple chemical structures you can look at chemfig -- I don't use it much though. http://www.ctan.org/tex-archive/macros/latex/contrib/chemfig/

For drawing simple MO diagrammes, modiagram is very pretty: http://www.ctan.org/pkg/modiagram

For drawing NMR pulse sequences there are a few options: http://verahill.blogspot.com.au/2013/08/499-briefly-drawing-nmr-sequences-using.html and http://verahill.blogspot.com.au/2013/08/498-briefly-drawing-nmr-pulse-sequences.html


A dead end: endiagram
It looks very promising, but it didn't work out for me: http://ctan.mirrorcatalogs.com/macros/latex/contrib/endiagram/

Installation:
mkdir ~/texmf/tex/latex/endiagram -p
cd ~/texmf/tex/latex/endiagram
wget http://ctan.mirrorcatalogs.com/macros/latex/contrib/endiagram/endiagram.sty
sudo texhash

You'll need siunitx and tikz as well, but it seems to come with a standard texlive install on debian. Out of the box I kept getting:

! Undefined control sequence.
<argument> \clist_count:N
\l__endiagram_points_clist

l.16 \ENcurve{1,4,0}

In the end I couldn't get it to work properly, even after installing l3kernel -- I don't think it would've been impossible to figure it out, but I was running out of patience.

The solution: pgfplots
So I kept looking, and found this: https://quantumchemistryniser.wordpress.com/2013/05/25/potential-energy-profile-using-pgfplots/

While I couldn't get it to work 'out of the box' (after deleting the nodes depending on the pdf files), I ended up reading the pfgplots manual: http://pgfplots.sourceforge.net/pgfplots.pdf

pgfplots is not meant for drawing potential energy diagrammes, but it can be made to do it -- it's 'dum' in the sense that it's not aware of what a PE diagram is, so you'll have to draw all objects expliticly. In the end, it's actually quite simple though.

I eventually ended up with these two examples:
The code is here:
\documentclass[10pt,a4paper]{article} \usepackage{pgfplots} \usepackage{tikz} \begin{document} %\begin{center} %\begin{tikzpicture}[scale=1.0] %\draw (0,0) --(1,2); %\end{tikzpicture} %\end{center} \begin{tikzpicture} \begin{axis}[ axis x line= bottom, axis y line= left, xmin=-1, xmax=10, ymin=-1, ymax=6, xlabel=Reaction coordinate, ylabel=$\Delta$E (kcal/mol), xtick=\empty ] \addplot[smooth,solid,blue] coordinates { (0,0)(1,0) (2,4)(3,4) (4,3)(5,3) (6,4)(7,4) (8,1)(9,1)}; \node at (axis cs:4.5,2.5) {Intermediate}; \end{axis} \end{tikzpicture} \begin{tikzpicture} \begin{axis}[ axis x line= bottom, axis y line= left, xmin=-1, xmax=6, ymin=-1, ymax=15, xlabel=Reaction coordinate, ylabel=$\Delta$E (kcal/mol), xtick=\empty ] \addplot[smooth,solid,blue] coordinates { (0,0)(1,0)}; \addplot[smooth,dotted,black] coordinates {(1,0)(2,11.7)}; \addplot[smooth,solid,blue] coordinates {(2,11.7)(3,11.7)}; \addplot[smooth,dotted,black] coordinates {(3,11.7)(4,10.5)}; \addplot[smooth,solid,blue] coordinates {(4,10.5)(5,10.5)}; \end{axis} \end{tikzpicture} \end{document}