09 May 2014

574. Texmaker and texlive on windows xp

There are two ways of dealing with latex on windows -- either using native packages or via cygwin. Here's the  native approach, which I tested in a virtual machine with Windows XP SP2

 
1. Install texlive

Go to http://www.tug.org/texlive/acquire-netinstall.html and download http://mirror.ctan.org/systems/texlive/tlnet/install-tl.exe

Run the file. You'll now be taken through the installation of texlive. Note that the full installation is ca 3.7 Gb and it will take a few hours to download and install. On the other hand, space is cheap and most people (in academia) don't pay for bandwidth, so it's not a bad idea to do the full install.

Anyway, here are a few screenshots of the installation process:



It's a good idea to change the mirror to speed up the download



Uncheck TexWorks since we'll be installing TexMaker


This step can take many hours


Finally done.


2. Install texmaker

Go to http://www.xm1math.net/texmaker/download.html and download http://www.xm1math.net/texmaker/texmakerwin32_install.exe

The same file will work on XP, Vista and 8 (and presumably 7, which is more or less a patched version of Vista) and it will work on both 32 and 64 bit systems.

Install texmaker.


3. Configure  texmaker
Start texmaker

Go to Options/Configure Texmaker.

Under Commands you can select to use an external pdf viewer. Note that you will need to make sure that the path is correct -- in my case it was pointing to adobe reader 11, whereas I had adobe reader 9 installed. Easy enough to change, but you need to do it manually. The embedded/internal pdf viewer works ok, but distorts the text and figures somewhat (everything got a bit squashed)
Choose internal or external pdf viewer. Make sure the path is correct
Under Quick Build you can tick Latex+Bib(la)tex+Latex(x2)+dvips+ps2pdf+View pdf. NOTE: if you do this you won't be able to compile any file which hasn't got a \cite command and a mathing .bib file.

Alternatively, pick latex + dvips + ps2pdf + View pdf.

Quick Build -- pick the one with bibtex in it
Under Editor you can disable code completion (which can get annoying at times):

You can now load a tex file and hit F1 to compile it:


Quick test example

0. Create a folder called e.g. testtex
 
1. Download UCSD.eps from here: http://vectorlogotypes.net/logo/68332_UCSD.htm

Put it in the testtex folder.


2. Create the following anothertest.bib file in either texmaker or notepad:
@Article{2014:example,
  AUTHOR = {Placeholder, A},
  TITLE = {Comprehensive title},
  YEAR = 2014,
  JOURNAL = {J. Comp. Chem.},
  VOLUME ={45},
  PAGES = {100-101}
}
Put it in the testtex folder.

3. Create a new tex file in texmaker:


Make sure to tick graphicx

Basic tex file
Save to your testtex folder.

4. Edit your tex file as shown below::
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}

\usepackage{url}
\title{This is a test}

\begin{document}

\section{The test}
This is a simple test which consists of inserting a figure and adding a reference via bibtex. You can download the logo from \url{http://vectorlogotypes.net/logo/68332_UCSD.htm}. Put the UCSD.eps file in the same directory as your .tex file.
\begin{figure}
 \includegraphics{UCSD.eps}
 \caption{UC San Diego logo.}
 \label{fig:test}
\end{figure}

Here's a citation.\cite{2014:example}

\bibliography{anothertest}
\bibliographystyle{ChemEurJ}
\end{document}
5. Compile.
If you set up your F1 as shown above (i.e. with bibtex support), then all you need to do is hit F1. Otherwise, if you used the alternative setup, do F2 (latex), F11 (bibtex), F2 (latex), F11 (bibtex), F1 (compile and view).

20 April 2014

573. PCSensors K-type USB thermocouple adapter TEMPer1K4 (0c45:7403) on debian

UPDATE 1 May 2014:
I've rewritten the code now to properly deal with the presence of both a 0c45:7401 and a 0c45:7403 simultaneously. Note that I'm not convince about the accuracy of the temperature readings (accuracy as in whether there's any systematic bias to the output. The reproducibility seems to be excellent though).

Original post:
I just received this usb thermocouple reader (TEMPer1k4): http://www.pcsensor.com/index.php?_a=product&product_id=104

About the product:
lsusb shows 0c45:7403 (Microdia Foot Switch)

dmesg shows
[13448.536120] usb 6-1: new low-speed USB device number 3 using uhci_hcd [13448.709126] usb 6-1: New USB device found, idVendor=0c45, idProduct=7403 [13448.709139] usb 6-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [13448.709146] usb 6-1: Product: TH1000isoV1.5 [13448.709152] usb 6-1: Manufacturer: RDing


Getting it to work:
You can use the same program as in this post: http://verahill.blogspot.com.au/2013/12/532-temper-temperature-monitoring-usb.html with some minor modifications. Before running
sudo python setup.py install

make some changes in temperusb/temper.py.

Firstly, you need to allow for the detection of devices with the 0c45:7403 ID
 
15 VIDPIDs = [(0x0c45L,0x7401L),(0x0c45L,0x7403L)]
Secondly, you need to make sure that the program knows which device is which and treats them differently. Finally, you need to collect the right data-- the TEMPer1k4 returns a data_s with a length of 8 (caveat -- I haven't checked what the output from 0c45:7401 looks like. Maybe it too yields 8 fields), and the [2:4] data block contains the internal temperature of the USB device, while the [4:6] data block holds the thermocouple junction temperature. Of a sort -- you get a number which you need to translate into a temperature. See the bottom of this post for how I worked it all out. Please note that you should calibrate the thermocouple -- the uncorrected output seems to be at least 2-3 degrees too high.
temper.py
 
 15 VIDPIDs = [(0x0c45L,0x7401L),(0x0c45L,0x7403L)]

 63     def getid(self):
 64         return self._device.idProduct

125             if self._device.idProduct==29697:
126                 temp_c = 125.0/32000.0*(struct.unpack('>h', data_s[2:4])[0])+0.0025
127                 if format == 'celsius':
128                     temp_c = temp_c * self._scale + self._offset
129                     return temp_c
130                 elif format == 'fahrenheit':
131                     return temp_c*1.8+32.0
132                 elif format == 'millicelsius':
133                     return int(temp_c*1000)
134                 else:
135                     raise ValueError("Unknown format")
136             elif self._device.idProduct==29699:
137                 temp_c = (struct.unpack('>h', data_s[4:6])[0])*0.25-2.00
138                 temp_internal=(125.0/32000.0*(struct.unpack('>h', data_s[2:4])[0]))+0.0025
139                 if format == 'celsius':
140                     temp_c = temp_c * self._scale + self._offset
141                     return temp_c
142                 elif format == 'fahrenheit':
143                     if self._device.idProduct==29697: #0x7401
144                         return temp_c*1.8+32.0
145                     elif self._device.idProduct==29699: #0x7403
146                         return temp_internal
147 

cli.py
 
 31     for i, dev in enumerate(devs):
 32         readings.append({'device': i,
 33                          'id':dev.getid(),
 34                          'temperature_c': dev.get_temperature(),
 35                          'temperature_f':
 36                          dev.get_temperature(format="fahrenheit"),
 37                          'ports': dev.get_ports(),
 38                          'bus': dev.get_bus()
 39                          })
 40 
 41     for reading in readings:
 42         if disp_ports:
 43             portinfo = " (bus %s - port %s)" % (reading['bus'],
 44                                                 reading['ports'])
 45         else:
 46             portinfo = ""
 47         if reading['id']==29697:
 48             print('Device #%i%s: %0.1f°C %0.1f°F'
 49                   % (reading['device'],
 50                      portinfo,
 51                      reading['temperature_c'],
 52                      reading['temperature_f']))
 53         elif reading['id']==29699:
 54             print('Device #%i%s: %0.1f°C %0.1f°C'
 55                   % (reading['device'],
 56                      portinfo,
 57                      reading['temperature_c'],
 58                      reading['temperature_f']))

Beyond this, follow the instructions in http://verahill.blogspot.com.au/2013/12/532-temper-temperature-monitoring-usb.html and make sure to set up a rules file with the correct USB ID for this device.

Done!

If you're curious about the details, have a look below.

Analysing USB traffic:
Since I wasn't quite sure where to start I figured the easiest approach would be to sniff the traffic between the usb device and the offically supported programme from PC Sensors. So I installed it Win XP in virtualbox, read a couple of temperatures and compared them with the captured data.

To capture data I did:
sudo apt-get install tshark
sudo modprobe usbmon
lsusb
Bus 008 Device 003: ID 17ef:4815 Lenovo Integrated Webcam [R5U877] Bus 008 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 043: ID 0c45:7403 Microdia Foot Switch Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
sudo tshark -D
1. eth0 2. wlan0 3. nflog 4. nfqueue 5. usbmon1 6. usbmon2 7. usbmon3 8. usbmon4 9. usbmon5 10. usbmon6 11. usbmon7 12. usbmon8 13. any 14. lo (Loopback)
touch 1.pcap chmod ugo+w 1.pcap sudo tshark -i usbmon4 -w $HOME/1.pcap

I opened the 1.pcap file in wireshark and looked for fields called leftover data.

Here are two examples of such 'leftover data' fields:
Host to USB: 01 80 00 00 00 00 00 00
USB to Host: 80 06 17 f0 00 5c 0f ff

Subjecting the system to different temperatures helped me figure out what fields where changing -- I've marked them in bold above (blue for the thermocouple, red for the internal temperature). Interestingly, I got overflow when freezing the thermocouple between two ice cubes, which indicated that there was a fairly high lower limit (1.5 degrees)
The following are some of the data I harvested. The temperature is in the first column, the hex code is in the second one and the decimal value is in the third one:
Internal:
23.63 17a 378
23.69 17b 379
23.94 17f 383
23.75 17c 380
21.88 15e 350
22.31 165 357
22.88 16e 366

Thermocouple: 23.75 05f 95 23.50 05e 9 38.25 099 153 24.00 066 102 87.50 15e 350 79.50 13e 318
In other words, T(thermo)=output(thermo)*0.25+1.50 and T(int.)=(output(int.)-0.0025)/0.0625. Because the internal data is in fields 2:4 it's seen as e.g. 17b0 instead of 17b, so the decimal version needs to be divided by 16 (line 126 above).

I also set up an /etc/temper.conf file and did chown $USER /etc/temper.conf in order to be able to read it (must be a better way). I tried to calibrate the thermocouple in my kitchen with iced water and boiling water. The boiling water gave a reading of 102 degrees, while the iced water gave me 7.5 degrees Celsius even after what should've been long enough to achieve equilibrium. I'll calibrate it in the lab later. So for now a simple offset might be enough to give a working temperature.
temper-poll -p
Device #0 (bus 2 - port 2)
so temper.conf became
2-2: scale = 1.00, offset = -4.0


The temper-usb code is changing too quickly!. You'll thus need to read and understand the code rather than just pasting it in. Here are the full, edited cli.py an temper.py files.

cli.py
# encoding: utf-8
from __future__ import print_function
from temper import TemperHandler


def main():
    th = TemperHandler()
    devs = th.get_devices()
    readings = []
    print("Found %i devices" % len(devs))

    for i, dev in enumerate(devs):
        readings.append({'device': i,
                         'id':dev.getid(),
                         'temperature_c': dev.get_temperature(),
                         'temperature_f':
                         dev.get_temperature(format="fahrenheit")
                         })

    for reading in readings:
  if reading['id']==29697:
   print('Device #%i: %0.1f°C %0.1f°F' % (reading['device'],
                                               reading['temperature_c'],
                                               reading['temperature_f']))
  elif reading['id']==29699:
   print('Device #%i: %0.1f°C %0.1f°C' % (reading['device'],
                                               reading['temperature_c'],
                                               reading['temperature_f']))

temper.py
# encoding: utf-8
#
# Handles devices reporting themselves as USB VID/PID 0C45:7401 (mine also says RDing TEMPerV1.2).
#
# Copyright 2012, 2013 Philipp Adelt 
#
# This code is licensed under the GNU public license (GPL). See LICENSE.md for details.

import usb
import sys
import struct

VIDPIDs = [(0x0c45L,0x7401L),(0x0c45L,0x7402L),(0x0c45L,0x7403L)]
REQ_INT_LEN = 8
REQ_BULK_LEN = 8
TIMEOUT = 2000

class TemperDevice():
    def __init__(self, device):
        self._device = device
        self._handle = None

    def get_temperature(self, format='celsius'):
        try:
            if not self._handle:
                self._handle = self._device.open()
                try:
                    self._handle.detachKernelDriver(0)
                except usb.USBError:
                    pass
                try:
                    self._handle.detachKernelDriver(1)
                except usb.USBError:
                    pass
                self._handle.setConfiguration(1)
                self._handle.claimInterface(0)
                self._handle.claimInterface(1)
                self._handle.controlMsg(requestType=0x21, request=0x09, value=0x0201, index=0x00, buffer="\x01\x01", timeout=TIMEOUT) # ini_control_transfer

            self._control_transfer(self._handle, "\x01\x80\x33\x01\x00\x00\x00\x00") # uTemperatura
            self._interrupt_read(self._handle)
            self._control_transfer(self._handle, "\x01\x82\x77\x01\x00\x00\x00\x00") # uIni1
            self._interrupt_read(self._handle)
            self._control_transfer(self._handle, "\x01\x86\xff\x01\x00\x00\x00\x00") # uIni2
            self._interrupt_read(self._handle)
            self._interrupt_read(self._handle)
            self._control_transfer(self._handle, "\x01\x80\x33\x01\x00\x00\x00\x00") # uTemperatura
            data = self._interrupt_read(self._handle)
            data_s = "".join([chr(byte) for byte in data])

            if self._device.idProduct==29697: 
    temp_c = 125.0/32000.0*(struct.unpack('>h', data_s[2:4])[0])+0.0025
    if format == 'celsius':
     return temp_c
    elif format == 'fahrenheit':
     return temp_c*1.8+32.0
    elif format == 'millicelsius':
     return int(temp_c*1000)
    else:
     raise ValueError("Unknown format")
            elif self._device.idProduct==29699: 
    temp_c = (struct.unpack('>h', data_s[4:6])[0])*0.25-4.00
    temp_internal=(125.0/32000.0*(struct.unpack('>h', data_s[2:4])[0]))+0.0025
    if format == 'celsius':
     return temp_c
    elif format == 'fahrenheit':
     if self._device.idProduct==29697: #0x7401
      return temp_c*1.8+32.0
     elif self._device.idProduct==29699: #0x7403
      return temp_internal
    elif format == 'millicelsius':
     return int(temp_c*1000)
    else:
     raise ValueError("Unknown format")
        except usb.USBError, e:
            self.close()
            if "not permitted" in str(e):
                raise Exception("Permission problem accessing USB. Maybe I need to run as root?")
            else:
                raise
    
    def getid(self):
        #print self._device.idProduct
        return self._device.idProduct

    def close(self):
        if self._handle:
            try:
                self._handle.releaseInterface()
            except ValueError:
                pass
            self._handle = None

    def _control_transfer(self, handle, data):
        handle.controlMsg(requestType=0x21, request=0x09, value=0x0200, index=0x01, buffer=data, timeout=TIMEOUT)

    def _interrupt_read(self, handle):
        return handle.interruptRead(0x82, REQ_INT_LEN)

        
class TemperHandler():
    def __init__(self):
        busses = usb.busses()
        self._devices = []
        for bus in busses:
            self._devices.extend([TemperDevice(x) for x in bus.devices if (x.idVendor,x.idProduct) in VIDPIDs])

    def get_devices(self):
        return self._devices

16 April 2014

572. autorotate/superimpose python script

If you want to calculate reaction coordinates between two structures you need to make sure that the structures haven't been rotated or translated, something which easily happens if you allow symmetry in gaussian and (it seems) z-matrix in nwchem.

I've written a script that lets you take two structures and align and superimpose them so that only the atoms that take part in the reaction move.

It works by you defining a minimum of four atoms that aren't supposed to move /relative to each other/ (i.e. they can be translated/rotated --- just not relative to each other) between the two structures. Four atoms far from each other are ideal. You need to make sure that they also don't lie in the same plane, but form a three-dimensional space.

I've tried this on real molecules too and it works better than I'd ever dared to hope for. The more 'stationary' atoms that you can use to make up the transformation matrix, the better.


Example:
In this example atom F is in a different location in structures a and b. The structures have also been rotated relative to each other.

a.xyz
6 A A 0.00000 0.00000 1.00000 B 0.00000 1.00000 0.00000 C 1.00000 0.00000 0.00000 D -1.00000 0.00000 0.00000 E 0.00000 0.00000 -1.00000 F 0.00000 0.500000 0.00000
b.xyz
6 B A 1 0 0 B 0 1 0 C 0 0 -1 D 0 0 1 E -1 0 0 F 0 -1 0

./autorotate.py a.xyz b.xyz '1,2,3,4'
Selected atoms in molecules 1 and 2 ['A', 0.0, 0.0, 1.0] ['A', 1.0, 0.0, 0.0] ['B', 0.0, 1.0, 0.0] ['B', 0.0, 1.0, 0.0] ['C', 1.0, 0.0, 0.0] ['C', 0.0, 0.0, -1.0] ['D', -1.0, 0.0, 0.0] ['D', 0.0, 0.0, 1.0] Transformation max error: 3.33066907388e-16 Writing to a.rot.xyz

a.rot.xyz
6 A A 1.00000 0.00000 0.00000 B -0.00000 1.00000 -0.00000 C -0.00000 0.00000 -1.00000 D -0.00000 0.00000 1.00000 E -1.00000 -0.00000 -0.00000 F -0.00000 0.50000 -0.00000
This is how it looks (note that the axis aren't aligned with (1,0,0; 0,1,0; 0,0,1) but seem to go through the centre of the molecule):
a.xyz
a.rot.xyz


b.xyz





Code:
#!/usr/bin/python
import sys
import numpy as np

#autorotate input_1.xyz input_2.xyz '1,2,3,4'
# need to pick at least four atoms that are not in the same plane
# input_1.xyz will be rotated to align with input_2.xyz
# you pick at least four atoms that should have the same positions
# relative to one another (i.e. distance and relative geometry). These 
# are then used to calculate an affine transform matrix which is used 
# to rotate and translate structure input_1.xyz to overlap with 
# structure 2

def formatinput(argument):
 infile1=sys.argv[1]
 atoms=sys.argv[3]
 atoms=atoms.split(',')
 coord_sys=[]

 for n in atoms:
  coord_sys+=[int(n)-1]
 try:
  infile2=sys.argv[2]
 except:
  infile2=''
 infile=[infile1,infile2]
 return infile,coord_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 getcoords(rawdata,preamble,atoms):
 
 n=0
 cartesian=[]
 
 for structure in rawdata:
  n=n+1
  num="%03d" % (n,)
  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+=[[element,float(coords[1]),float(coords[2]),float(coords[3])]]
     
 return cartesian

def getstructures(rawdata,preamble):
 
 n=0
 cartesian=[]
 
 for structure in rawdata:
  n=n+1
  num="%03d" % (n,)
  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+=[coordinates]
     
 return cartesian

def affine_transform(atoms,structures):
# from http://stackoverflow.com/questions/20546182/how-to-perform-coordinates-affine-transformation-using-python-part-2
 primaryatomcoords=[]
 for n in atoms:
  primaryatomcoords+=[structures[0][n]]

 secondaryatomcoords=[]
 for n in atoms:
  secondaryatomcoords+=[structures[1][n]]

 primary = np.array(primaryatomcoords)
 secondary = np.array(secondaryatomcoords)
 primaryfull = np.array(structures[0])

 # Pad the data with ones, so that our transformation can do translations too
 n = primary.shape[0]
 pad = lambda x: np.hstack([x, np.ones((x.shape[0], 1))])
 unpad = lambda x: x[:,:-1]
 X = pad(primary)
 Y = pad(secondary)
 Xp= pad(primaryfull)

 # Solve the least squares problem X * A = Y
 # to find our transformation matrix A
 A, res, rank, s = np.linalg.lstsq(X, Y)

 transform = lambda x: unpad(np.dot(pad(x), A))

# print "Max error should be as small as possible if the rotation is successful"
# print "If max error is large you may have selected a bad set of atoms"
 print "Transformation max error:", np.abs(secondary - transform(primary)).max()
 secondaryfull=transform(primaryfull)
 return secondaryfull

def transform_xyz(tmatrix,newxyz):
 final_xyz=[]
 for n in newxyz:
  coord=np.mat(str(n[0])+';'+str(n[1])+';'+str(n[2]))
  newcoord=np.dot(tmatrix,coord)
  newcoord=np.matrix.tolist(newcoord)
  final_xyz+=[[ newcoord[0][0],newcoord[1][0],newcoord[2][0]]]
 return final_xyz

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 write_aligned(aligned_structure,atom_coords,preamble,outfile):
 outfile=outfile.replace('.xyz','.rot.xyz')
 print "Writing to ",outfile
 g=open(outfile,'w')
 g.write(str(preamble[0])+'\n'+str(preamble[1])+'\n')
 
 for n in range(0,len(aligned_structure)):
  xyzstring=genxyzstring(aligned_structure[n],atom_coords[n][0])
  g.write(xyzstring)
 g.close()
 return 0
 
if __name__ == "__main__":
 infile,atoms=formatinput(sys.argv)
 
 xyz=['','']
 preamble=['','']
 
 #get raw data
 xyz[0],preamble[0]=getrawdata(infile[0])
 xyz[1],preamble[1]=getrawdata(infile[1])

 atom_coords=[getcoords(xyz[0],preamble[0],atoms)]
 atom_coords+=[getcoords(xyz[1],preamble[1],atoms)]
 
 #collect structures from raw data
 structures=[getstructures(xyz[0],preamble[0])]
 structures+=[getstructures(xyz[1],preamble[1])]
 
 print "Selected atoms in molecules 1 and 2"
 for n in atoms:
  print atom_coords[0][n],atom_coords[1][n]
  
 #transform structure
 aligned_structure=affine_transform(atoms,structures)
 
 write_aligned(aligned_structure,atom_coords[0],preamble[0],str(infile[0]))