Macs in Chemistry

Insanely great science

 

Scripting Vortex 14

In tutorial 4 we looked at using the command line tool sddesc from Chemical Computing Group to calculate a number of molecular descriptors and then import them into Vortex. However there a couple of issues with doing this not the least ensuring all the environment variables are set correctly. An alternative is to use MOE as a web service and access the tools using the SOAP protocol (Simple Object Access Protocol). This protocol provides a specification for exchanging structured information in the implementation of Web Services in computer networks. It relies on XML Information Set for its message format.

The MOE Web Server

You can start the MOE web server using the following command in a Terminal window

prompt$ /Applications/moe2012/bin/moeweb

You should get a list of information including the IP address of the server and the port you need to address (usually port 8888)

You should also get a list of very useful web pages

YellowPages results now available:
    (1): [soap] DataTypes
    (2): [soap] DepictionLayout
    (3): [soap] MedChemProps
    (4): [soap] MolToSMILES
    (5): [soap] SMILESToMol
    (6): [soap] Version

If you now open a web browser and go to

http://localhost:8888/soap.html

You will get a web page giving a list of the available functions.

soap1

If like me you are not particularly familiar with constructing SOAP queries then these pages are invaluable. Select the SMILESToMol hyperlink and you should get the page below. Fill in a valid SMILES string and click on the “Preview SOAP Request” button and you can see the syntax of the expected SOAP request and this is what we will be included in the Vortex script as the SOAP request.

soap2

The MolToSMILES script

To start with I thought I’d create a script that retrieves the SMILES string from the web server, mainly because it avoids the complication of trying to parse the returned XML if there are multiple properties. We do however need to import an XML parsing library. The Element type is a flexible container object, designed to store hierarchical data structures in memory. The type can be described as a cross between a list and a dictionary, XML is an inherently hierarchical data format, and the most natural way to represent it is with a tree.

import xml.etree.ElementTree as ET

The first part just allows the user to confirm that they are not posting proprietary information to an external web service. We then get the structure as a MOL file.

mymol = vortex.getMolProperty(mfm.getMolFileAtRow(r), 'MOL')

Then we construct the SOAP request, we need the URL we are posting to and the data wrapped in the SOAP request format taken from the appropriate MOE SOAP function web page.

We then perform the request

request = urllib2.Request(url, data, headers=headers)
contents = urllib2.urlopen(request).read()

We then need to create a column in Vortex, and then parse the data, since there is only the SMILES string returned this is fairly straight-forward with help from Matt. The XML response from the MOE server is parsed using the python ElementTree module. This module parses an XML string using ET.fromstring() into a hierarchical tree data structure that allows us to easily pick out various values in the response. In this case, the desired value is just the text within a tag named "smiles", which can be found using a relatively simple XPath query:

   mysmiles = root.find('.//smiles')

This query recursively searches through the tree and returns the first element with the tag "smiles" that it finds. The text contents of that element is given by mysmiles.text

# Using MOE via a web service this uses a local copy of MOE
    # 

import sys
import com.dotmatics.vortex.util.Util as Util

if Util.getPlatform() == Util.PlatformIsWindows:
 sys.path.append(vortex.getVortexFolder() + '\\modules\\jythonconsole')
 sys.path.append(vortex.getVortexFolder() + '\\modules\\jythonlib')
else:
sys.path.append(vortex.getVortexFolder() + '/modules/jythonconsole')
sys.path.append(vortex.getVortexFolder() + '/modules/jythonlib')

import urllib2
import urllib
import xml.etree.ElementTree as ET

content = javax.swing.JPanel()

label = javax.swing.JLabel("<html><b>Make sure this uses a local web service</b><p><br>If you don't want to post your data to the internet press Cancel.</html>")

layout.fill(content, label, 2, 2)



ret = vortex.showInDialog(content, "MOE Web Service")

if ret == vortex.OK:

 mfm = vtable.getMolFileManager()
rows = vtable.getRealRowCount()
for r in range(0, rows):
    mymol = vortex.getMolProperty(mfm.getMolFileAtRow(r), 'MOL')


    url ='http://yourserver.local:8888/soap/MolToSMILES'

    data = '''<?xml version="1.0"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Body>
    <InputType>
    <molecule><![CDATA[%s]]></molecule>
    </InputType>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>''' % mymol

    headers = {
    'Content-Type': 'text/html',
    'Content-Length': len(data)
    }

    request = urllib2.Request(url, data, headers=headers)
    contents = urllib2.urlopen(request).read()

# Create new columns in table if needed

    column = vtable.findColumnWithName('SMILES', 1, 3)
    vtable.fireTableStructureChanged()

# Parse response

    root = ET.fromstring(contents)
    if root.tag == 'error':
        print 'Error from MOE server:'
        print root.text
    else:

        mysmiles = root.find('.//smiles')

    if mysmiles is not None:
        column = vtable.findColumnWithName('SMILES', 1, 3)
        column.setValueFromString(r, mysmiles.text)
        print mysmiles.text
    else:
            print 'Could not parse response:'
            print contents


vtable.fireTableStructureChanged()

The result of running this script is a new column called SMILES, and because Vortex is smart enough to realise what the contents are the SMILES strings get automatically rendered as 2D images.

mol2smiles

You can download the script from here MOESoapMolToSmiles.vpy.zip