Macs in Chemistry

Insanely great science

 

Scripting Vortex (and MOE) 15

Getting MOE to listen

One of the new features in the latest version of MOE from Chemical Computing Group is the Listener. The MOE socket listener provides an alternative to MOE/web for executing functions remotely on a running instance of MOE. These special functions must follow a naming convention in which each name is prefixed by the string listen_. Furthermore, each such function is permitted only a single argument in the form of a tagged vector. It is the responsibility of the function author to validate the number and type of arguments, and any other constraints. The function should simply exit with an error if called with invalid arguments. Once such functions are loaded into an instance of MOE and the listener is activated, they can be executed from a web browser or any other application by providing an appropriately constructed URL.

The listenfunctions must be loaded into a running instance of MOE using the SVL load command before they can be called. To make use of these functions, the listener (i.e. server) must first be started. This is accomplished using the SVL listenport command from the SVL command window.

svl> listen_port 8989

Unfortunately the documentation is very sparse but you need to note that the listener provides little or no feedback other than “OK”.

Any HTTP client may be used to make the requests, e.g. a web browser, wget, or even a custom application. MOE will respond with HTTP/1.0 200 OK followed by the text OK if the request was processed and understood, or an error if the request was malformed or invalid. If the request was valid but the URL was not in the form described above (for example no exec) or the function itself exits with an error, an error window will pop up within MOE; note that in such cases, OK will still be returned to the HTTP client.

To demonstrate what sort of thing is possible I’m making use of a piece of SVL taken from a demo created by CCG. there are two listen_functions.

The SVL Script

Scientific Vector Language is a high-performance programming language built into the MOE Molecular Operating Environment. SVL is an embedded language; that is, its compiler and run-time environment are an integral part of MOE. SVL serves as the command, macro, scripting, and high-performance computing language of MOE. SVL Exchange is a repository of programs and code samples written in the Scientific Vector Language (SVL) by users and developers and is a great place to get started.

This version of the SVL script has been annotated by Simon Grimshaw of CCG to aid understanding of how it works. It provides the functionality to download from PDB structures from the rcsb Protein Data Bank however it could be modified to download from an in house database. The script also the functionality to create 3D structures from SMILES strings and do the alignment.

#svl
//  moe_custom_listener.svl  sample functions to demo MOE listener
//
//
//  22-sep-2013 (sg) created
//
//
//  DESCRIPTION:
//  Functions for allowing MOE to be remote controlled via the HTTP
//  listener.
//
//  listen_getrcsb arg
//  where arg is a tagged vector of comma separated PDB codes, e.g.
//  [req_id:'1g5s,1ke8,1m17']
//  Output is a database in the CWD of structures; the database browser
//  is started automatically.
//
//  listen_showlig_smiles arg
//  where arg is a tagged vector with a single SMILES string, e.g.
//  [smiles:'c1ccccc1']
//  The molecule will be created in MOE, and if a ligand is in the system,
//  the new molecule will be aligned to the existing ligand via Flexible
//  Alignment.
//
//  USAGE:
//
//  1.  Save and load this function
//  2.  At the SVL command line prompt type the following
//
//  svl>  listen_port 8989
//
//  where,
//
//  8989 is the number of port on which MOE will listen
//
//  Send requests to:
//  http:   //localhost:8989/exec/showlig_smiles?smiles=c1ccccc1
//  http:   //localhost:8989/exec/getrcsb?req_id=1g5s,1ke8,1m17
//
//
// COPYRIGHT (C) 2013 CHEMICAL COMPUTING GROUP INC.  ALL RIGHTS RESERVED.
//
// PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE IS HEREBY
// GRANTED PROVIDED THAT: (1) UNMODIFIED OR FUNCTIONALLY EQUIVALENT CODE
// DERIVED FROM THIS SOFTWARE MUST CONTAIN THIS NOTICE; (2) ALL CODE DERIVED
// FROM THIS SOFTWARE MUST ACKNOWLEDGE THE AUTHOR(S) AND INSTITUTION(S); (3)
// THE NAMES OF THE AUTHOR(S) AND INSTITUTION(S) NOT BE USED IN ADVERTISING
// OR PUBLICITY PERTAINING TO THE DISTRIBUTION OF THE SOFTWARE WITHOUT
// SPECIFIC, WRITTEN PRIOR PERMISSION; (4) ALL CODE DERIVED FROM THIS SOFTWARE
// BE EXECUTED WITH THE MOLECULAR OPERATING ENVIRONMENT (MOE) LICENSED FROM
// CHEMICAL COMPUTING GROUP INC.
//
// CHEMICAL COMPUTING GROUP INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
// SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
// AND IN NO EVENT SHALL CHEMICAL COMPUTING GROUP INC. BE LIABLE FOR ANY
// SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
// RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
// CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.


// http:    //localhost:8989/exec/test?var1=123&var2=abc

function conf_Embed3D, Superpose, _Atoms, FlexAlign;

function ph4_aHydrophobe, ph4_aPlanar, ph4_aAcceptor, ph4_aDonor;
function ph4_aTautomerAcceptor, ph4_aTautomerDonor;

    // a set of positions based on pharmacophore features because Superpose 
    // relies on identical numbers of reference points for each molecule
local function getpos atoms
    return tr [
    oCentroid atoms,
    oCentroid (atoms | ph4_aHydrophobe atoms),
    oCentroid (atoms | ph4_aPlanar atoms),
    oCentroid (atoms | ph4_aAcceptor atoms or ph4_aTautomerAcceptor atoms),
    oCentroid (atoms | ph4_aDonor atoms or ph4_aTautomerDonor atoms)
    ];
endfunction

    // Superpose qat onto refat based on ph4 features defined in getpos
local function quickalign [refat, qat]
        local [A,B] = app getpos [refat, qat];
        local [msd, R, t] = Superpose [[A,B]];
       aSetPos [qat, app add (R(2) * [aPos qat - t(2)]) + t(1)];
endfunction

// Download a given set of PDB codes and save them to a temporary database
global function listen_getrcsb arg
    local pdbids = first cat sread [string arg.req_id, '{t:*|,}'];
    local dloads = rcsb_download [pdbids, [directory: DOWNLOADS]];

    // discard any failed downloads
 dloads = dloads | second untag dloads <> 'failed';

    // create the databases and switch to a private system
    // download, open and write each file to the database
    local mdb = db_Open [fnametemp 'webfiles_*.mdb', 'create'];
    db_CreateField [mdb, 'mol', 'molecule'];
    local skey = SystemPush [];
    local i, file;
 for i = 1, length dloads loop
    Close[force:1];
    file = pr twrite ['$DOWNLOADS/{}.ent.gz', tolower first dloads(i)];
    ReadPDB file;
    db_Write [mdb, 0, [mol:mol_Extract Chains[]]];
    endloop
    SystemPop skey;

    local mdbname = db_Filename mdb;
    dbv_Open mdbname;
    db_Close mdb;

    // run the database browser
    run'dbbrowse.svl';
endfunction

// create a new molecule in MOE based on SMILES. If a ligand is already 
// present in the system, use FlexAlign to align the incoming molecule to 
// the existing ligand
global function listen_showlig_smiles arg
  local smiles = first cat sread [string arg.smiles, '{t:*|,}'];

    // switch to a private system, create the molecule from SMILES
    // then use conf_Embed3D to generate an unstrained conformation
    // then extract the db mol vector and return to the main system
local [sk1, sk2] = SystemPush [];
local atoms = sm_Build smiles;
conf_Embed3D atoms;
local mol = mol_Extract atoms;
SystemPop [sk1, sk2];

    // check for a ligand, and if one is found, align the incoming 
    // molecule to the reference ligand
local lig = _Atoms'$$ligand';
 if length lig then
[sk1, sk2, lig] = SystemPush lig;
local newligch = mol_Create mol;
quickalign [lig, cat cAtoms newligch];
aSetFixed [lig, 1];
        // FlexAlign the new molecule onto the reference in "refine" mode
FlexAlign [mode:'flexible', file:'', dump:0, maxit:1];
mol = mol_Extract newligch;
SystemPop [sk1, sk2];
 endif

    // create the new molecule and set the view point to look at 
    // new molecule
 ViewObj mol_Create mol;
endfunction

You can download the SVL script here moecustomlistener.svl.zip

The Vortex scripts

One of the very little publicised features available in Vortex is the ability to run context dependent scripts, these scripts execute a specific function dependent on the cursor selection. So selecting one field will execute one script, whilst selecting another will execute a different script. These scripts need to be stored in the “context” folder which is inside the “Vortex_Add-ons” folder.

moeweb1

If we now read in an sdf file that includes a column with the PDB codes for the crystal structure of a protein associated with a particular ligand, and then right-click on the PDB entry we get a drop down menu that allows you to navigate to the desired Vortex script as shown below.

contextScripts

The script will download the associated PDB structures from the rcsb Protein Data Bank, put them into a database then start the browser. It may take a few seconds to download the structure; this does rely on MOE having the right proxy settings to access the internet (use the Java console to set them). You can now transfer this to MOE and amend the display to highlight the ligand.

The MOEflexalign script takes the SMILES string of the selected row generates a 3D structure and does a one-shot flexalign between the ligand in the system in MOE, and the incoming ligand.

It is probably easier to see this in action, if it appears rather small click on the YouTube icon in the bottom right corner of the video.

The MoeGetPDB Vortex script

The first part of the script finds the column labelled “PDB” and then gets the pdb code. We then get all the variables needed by MOE and pass them to the “getrcsb” listener

 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

pdb = &lsquo;&rsquo;

col = vtable.findColumnWithName('PDB', 0)
if (col == None):
 vortex.alert('Load a workspace with a PDB column please.')
 quit()
else:
 pdb = col.getValueAsString(cell_row)


vortex.alert('PDB = '+pdb)

url = "http:    //localhost:8989/exec/getrcsb"   
values={'req_id':pdb}
data = urllib.urlencode(values)
headers = {'Content-type': 'application/x-www-form-urlencoded'}
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()

You can download the script here MOEGetPDB.vpy.zip

The FlexAlign Vortex script

This script follows a similar format, we first identify the structure column and then get the SMILES string of the selected molecule, we then get all the variables needed by MOE and pass them to the showlig_smiles listener .

# 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


smiles = ''

col = vtable.findColumnWithName('Structure', 0)

if (col == None):
col = vtable.findColumnWithName('SMILES', 0)
if (col == None):
     vortex.alert('Load a workspace with a Structure or SMILES column please.')
   quit()
 else:
     smiles = col.getValueAsString(cell_row)
else:
smiles = vortex.getMolProperty(vtable.getMolFileManager().getMolFileAtRow(cell_row), 'SMILES')

vortex.alert('SMILES = '+smiles)

url = "http:    //localhost:8989/exec/showlig_smiles"   
values={'smiles':smiles}
data = urllib.urlencode(values)
headers = {'Content-type': 'application/x-www-form-urlencoded'}
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()

You can download the script here MOEflexalign.vpy.zip

There are a number of other similar scripts in the Other Hints, Tips and Tutorials

Page Updated 27 September 2013