| Open Interface |

Label Molecule Single_property Monomer/Residue On CRN HW_hydrophobicity
The source file is prop_example.c. Also listed below are two BCL macros, hydro.bcl and flex.bcl. Hydro.bcl is a BCL version of the prop_example.c code. It is included here to show that both BCL and C can be used for function properties, but BCL function properties may be too slow in Insight. Flex.bcl is an example of an Attribute property macro. It is included to show an alternative to functional properties.
The first one, named atom_example.c, creates a new module and command which accepts the specifications of two atoms to define a rotation axis, a set of atoms to rotate, and an angle to rotate them through. It demonstrates setting up the user interface, retrieving input from the user, and modifying atom attributes (in this case atom coordinates).
The second one, named mopac_example.c, creates and new module and command which demonstrates running another program from a command. In this case the program is mopac and is used to optimize the specified structure.
The client program takes the name of the host on which Insight II is running (used by the client to locate Insight II since you can run the client on another workstation if you wish) and the specifications of two bonded atoms. The distance between the two atoms is reported and their bond lenth is increased by one Angstrom.

NOTE: These instructions are for SGI running IRIX 6. If you are running IRIX 5, substitute the IRIX 5 makefile in step 3.
setenv LD_LIBRARY_PATH .\:$LD_LIBRARY_PATH

# MAKEFILE_IRIX6
# Example Makefile for doing insightII development.
# This version is for irix6 and uses dynamic
# shared objects.
#
#
# Put the list of object files you wish to include in insight here
#
OBJS = oi_customize.o atom_example.o mopac_example.o prop_example.o
SRCS = $(OBJS:.o=.c)
include /usr/include/make/commondefs
DEF_CSTYLE = $(CSTYLE_N32_M3)
LCOPTS = -DGL_LIB -g -G 0
#OPTIMIZER = -O1
IN2SRC = $(BIOSYM)/source
LCINCS = -I. -I/usr/include/bsd -I$(IN2SRC)/utilbench/include -I$(INSIGHT_HELP) -I$(IN2SRC)/chembench/include -I$(IN2SRC)/wb/include
insightII: $(OBJS)
cp $(BIOSYM)/irix6m3/library/insight/libuser.a .
ar clruvb define_user_modules.o libuser.a $(OBJS)
ld $(DEF_CSTYLE) -shared -all libuser.a -o libuser.so
lint:
lint $(LCINCS) $(SRCS)
#
# Put any dependencies here
#

/******************************************************************************
*+
* PROP_EXAMPLE.C
*
* Principal function:
* Demonstrates definition of a property.
*
*
*-
*/
#include "prop.h"
static boolean_c eval_monomer_using_hydro (
void *owner_obj,
void *obj,
long *data,
double *result
);
/********************************************************************************
* DEFINE_USER_PROPS
*
* Do the initial setup: create the property and add it to the system.
*/
void define_user_props()
{
prop_c prop;
status_descr_c status;
prop_new (&prop, "HW_hydrophobicity", Monomer_class_id, Float_Range,
eval_monomer_using_hydro, NULL, &status);
system_add_prop (g_system, prop, &status);
}
/********************************************************************************
* EVAL_MONOMER_USING_HYDRO
*
* Evaluation function: given a residue, calculate its
* hopp-woods hydrophobicity value.
*/
static boolean_c eval_monomer_using_hydro (
void *owner_obj,
void *obj,
long *data,
double *result
)
{
status_descr_c status;
char c;
if (monomer_get_1let_type(obj, &c, &status)){
switch(c){
case `A':
*result = -1.6;
break;
case `V':
*result = -2.6;
break;
case `L':
*result = -2.8;
break;
case `I':
*result = -3.1;
break;
case `P':
*result = 0.2;
break;
case `F':
*result = -3.7;
break;
case `W':
*result = -1.9;
break;
case `M':
*result = -3.4;
break;
case `G':
*result = -1.0;
break;
case `S':
*result = -0.6;
break;
case `T':
*result = -1.2;
break;
case `C':
*result = -2.0;
break;
case `Y':
*result = 0.7;
break;
case `N':
*result = 4.8;
break;
case `Q':
*result = 4.1;
break;
case `D':
*result = 9.2;
break;
case `E':
*result = 8.2;
break;
case `K':
*result = 8.8;
break;
case `R':
*result = 12.3;
break;
case `H':
*result = 3.0;
break;
}
}
else{
*result = 0.0;
}
return(TRUE);
}
# Hopp-Woods hydrophobicity values
define_macro float hw_hydro ident mon
lstring the_type
the_type = {prop_get_str type_1letter monomer $mon}
if ($the_type == "A")
return -0.5
end
if ($the_type == "V")
return -1.8
end
if ($the_type == "I")
return -1.8
end
if ($the_type == "P")
return 0
end
if ($the_type == "F")
return -2.5
end
if ($the_type == "W")
return -3.4
end
if ($the_type == "M")
return -1.3
end
if ($the_type == "G")
return 0
end
if ($the_type == "S")
return 0.3
end
if ($the_type == "T")
return -0.4
end
if ($the_type == "C")
return -1.0
end
if ($the_type == "Y")
return -2.3
end
if ($the_type == "N")
return 0.2
end
if ($the_type == "Q")
return 0.2
end
if ($the_type == "D")
return 3.0
end
if ($the_type == "E")
return 3.0
end
if ($the_type == "K")
return 3.0
end
if ($the_type == "R")
return 3.0
end
if ($the_type == "H")
return -0.5
end
return 0
end_macro
prop_register Func hw_hydrophob monomer float hw_hydro
# Flexibility property. Flexibility of atoms is computed from
# dynamics history file. To use, perform an dynamics
# simulation
# and load it into insight with the get trajectory command.
# Then execute this flex command to assign the flexibility
# values to the atoms.
#
define_macro flex ident the_mol
int frame, index
coord starts[10000]
float max_dist[10000], dist
float dx, dy, dz
coord the_coord
prop_register attr flexibility atom float
atom_list = {system_fetch_atom $the_mol}
count = sizeof($atom_list)
if ($count > 10000)
print "Maximum number of atoms exceeded. "
print "Increase size of max_dist and starts arrays."
return
end
analysis
the_frame_count = {animate $the_mol}
foreach $frame from 1 to 1
conformation frame $frame
foreach $index from 1 to $count
starts[$index] = {xyz $atom_list[$index]}
max_dist[$index] = 0
end
end
foreach $frame from 2 to $the_frame_count
conformation frame $frame
foreach $index from 1 to $count
the_coord = {xyz $atom_list[$index]}
dx = $starts[$index].x - $the_coord.x
dy = $starts[$index].y - $the_coord.y
dz = $starts[$index].z - $the_coord.z
dist = sqrt($dx * $dx + $dy * $dy + $dz * $dz)
if ($dist > $max_dist[$index])
$max_dist[$index] = $dist
end
end
end
foreach $index from 1 to $count
prop_set_float flexibility atom \
$atom_list[$index] $max_dist[$index]
end
unanimate $the_mol
end_macro
/******************************************************************************
*+
* ATOM_EXAMPLE.C
*
* Principal function:
* Example of Open Interface usage. Provides atom-related commands.
*
* Exported functions:
* void define_atom_example_module()
* Define the parameters and commands for
* the atom example module
*
* Private functions:
* static boolean_c do_my_spin();
* static boolean_c run_client();
*
* Usage:
*
* Revision history:
*
* Key words: define atom module
*
*-
*/
#include <stdio.h>
#include <oi.h>
#define MODULE_NAME "Atom_Example"
#define PULLDOWN_NAME "Atom_Commands"
#define ROTATE_COMMAND_NAME "spin_atom"
#define AXIS_ATOM1_P "first axis atom"
#define AXIS_ATOM2_P "second axis atom"
#define DEGREES_OF_ROTATION_P "degrees of rotation"
#define SPIN_ATOMS_P "atoms to spin"
#define CLIENT_COMMAND_NAME "run_client"
#define CLIENT_COMMAND "client command"
static boolean_c do_my_spin();
static boolean_c run_client();
/******************************************************************************
* DEFINE_ATOM_EXAMPLE_MODULE
*/
void define_atom_example_module ()
{
status_descr_c status;
/*
* Register a new module, no preview or postview functions.
*/
module_register(MODULE_NAME, 0, 0, 0, &status);
/*
* Add the module to the "Modules" menu.
*/
discipline_add_module(BIOCHEM, MODULE_NAME, 0, 0, &status);
/*
* Open the module.
*/
module_open(MODULE_NAME);
/*
* Define the pulldown.
*/
menu_new(PULLDOWN_NAME,0);
/*
* Now define the rotation command.
*/
menu_add_cmd(PULLDOWN_NAME, ROTATE_COMMAND_NAME, do_my_spin);
param_new(AXIS_ATOM1_P, tident);
cmd_use_insight_param(ROTATE_COMMAND_NAME, PULLDOWN_NAME, ATOM_SPEC,
AXIS_ATOM1_P, &status);
param_new(AXIS_ATOM2_P, tident);
cmd_use_insight_param(ROTATE_COMMAND_NAME, PULLDOWN_NAME, ATOM_SPEC,
AXIS_ATOM2_P, &status);
param_new(SPIN_ATOMS_P, tident);
cmd_use_insight_param(ROTATE_COMMAND_NAME, PULLDOWN_NAME, MOLECULE_SPEC,
SPIN_ATOMS_P, &status);
param_new(DEGREES_OF_ROTATION_P, treal);
cmd_add_param( PULLDOWN_NAME,ROTATE_COMMAND_NAME,
DEGREES_OF_ROTATION_P);
cmd_set_sideblock( PULLDOWN_NAME,ROTATE_COMMAND_NAME, 1);
/*
* Now define the run client command.
*/
menu_add_cmd(PULLDOWN_NAME, CLIENT_COMMAND_NAME, run_client);
param_new(CLIENT_COMMAND, tlstring);
cmd_add_param( PULLDOWN_NAME,CLIENT_COMMAND_NAME,
CLIENT_COMMAND);
/*
* Close the module.
*/
module_close(MODULE_NAME);
/*
* Make the menu.
*/
module_gen_menus(MODULE_NAME);
}
/******************************************************************************
* DO_MY_SPIN
*
* Spin the specified atoms around an axis defined by two
* atoms.
*
* This function gets called when the execute button in the parameter
* block has been pressed.
*/
static boolean_c do_my_spin(c, p, origin)
char *c;
char *p;
int origin;
{
long_string_c molecule_spec;
fetch_c fetch;
atom_c atom, axis_atom1, axis_atom2, *atoms=NULL;
mol_c mol, saved_mol;
monomer_c monomer;
status_descr_c status;
int count, i;
double degrees;
boolean_c success;
boolean_c return_status = FALSE;
/*
* Get the axis atoms that the user specified.
*/
if (!param_get_ident_scope( p,c, AXIS_ATOM1_P, molecule_spec))
goto error_exit;
fetch_init_insight(&fetch, molecule_spec, &status);
success = system_fetch_atom(g_system, &mol, &monomer,
&axis_atom1, &fetch, &status);
fetch_end(&fetch, &status);
if(!success)
goto error_exit;
if (!param_get_ident_scope( p,c, AXIS_ATOM2_P, molecule_spec))
goto error_exit;
fetch_init_insight(&fetch, molecule_spec, &status);
success = system_fetch_atom(g_system, &mol, &monomer,
&axis_atom2, &fetch, &status);
fetch_end(&fetch, &status);
if (!success)
goto error_exit;
/*
* Get the degrees of rotation.
*/
if (!param_get_real_scope( p,c, DEGREES_OF_ROTATION_P, °rees))
goto error_exit;
/*
* Get the atoms to be moved.
*/
if (!param_get_ident_scope( p,c, SPIN_ATOMS_P, molecule_spec))
goto error_exit;
fetch_init_insight(&fetch, molecule_spec, &status);
count = 0;
while(system_fetch_atom(g_system, &mol, &monomer, &atom, &fetch, &status)){
count++;
}
fetch_end(&fetch, &status);
if (count == 0)
goto error_exit;
atoms = (atom_c *)malloc(sizeof(atom_c) * count);
if (!atoms)
goto error_exit;
fetch_init_insight(&fetch, molecule_spec, &status);
i = 0;
while(system_fetch_atom(g_system, &mol, &monomer, &atom, &fetch, &status)){
atoms[i++] = atom;
saved_mol = mol;
}
fetch_end(&fetch, &status);
return_status = atom_rotate_2atom_axis(axis_atom1, axis_atom2, degrees,
atoms, count, &status);
free(atoms);
mol_rebuild_display(saved_mol, &status);
system_draw(g_system, &status);
error_exit:
return(return_status);
}
/******************************************************************************
* ATOM_ROTATE_2ATOM_AXIS
*
* Spin atoms around an axis defined by two atoms.
*
*/
boolean_c atom_rotate_2atom_axis (
atom_c axis_atom1,
atom_c axis_atom2,
double rotation,
atom_c atoms[],
int natoms,
status_descr_c *p_status
)
{
coord_c axis_coord1;
coord_c axis_coord2;
coord_c atom_coord;
coord_c new_coord;
transform_c transform;
int i;
boolean_c return_status = FALSE;
/*
* Make the transform.
*/
atom_get_coord (axis_atom1, &axis_coord1, p_status);
atom_get_coord (axis_atom2, &axis_coord2, p_status);
if (transform_new_axis_rotate_pt (&transform, axis_coord1,
axis_coord2,
rotation, p_status)){
/*
* Apply the transform to the specified atoms.
*/
for (i=0; i<natoms; i++) {
atom_get_coord (atoms[i], &atom_coord, p_status);
coord_transform (&new_coord, transform, atom_coord, p_status);
atom_set_coord (atoms[i], new_coord, p_status);
}
transform_delete(&transform, p_status);
return_status = TRUE;
}
return(return_status);
}
/******************************************************************************
*+
* MOPAC_EXAMPLE.C
*
* Principal function:
* Define the parameters and commands of the mopac_example module
* of commands.
*
* Exported functions:
* void define_mopac_example_module()
* Define the parameters and commands for
* the mopac_example module.
*
* Private functions:
* static boolean_c do_my_mopac(char *c, char *p, int origin)
* static boolean_c read_in_mopac(long mol_long, int job_status)
*
* Usage:
*
* Author:
*
* Revision history:
*
* Key words: define mopac example module
*
*-
*/
#include <ctype.h>
#include <oi.h>
#define MODULE_NAME "Mopac_Example"
#define PULLDOWN_NAME "Launch_mopac"
#define COMMAND_NAME "launch"
#define PARAMETER_NAME "Mol to minimize"
static boolean_c do_my_mopac(char *c, char *p, int origin);
static boolean_c read_in_mopac(long arg1, int status);
/******************************************************************************
* DEFINE_MOPAC_EXAMPLE_MODULE
*
* Define the mopac_example module.
*
* This function is to be called from the oi_customize() function in
* oi_customize_example.c. See oi_customize_example.c in the
* $BIOSYM_ROOT/$BIOSYM_CONTEXT/source/oi/oilib directory for an example
* of how to call this function.
*/
void define_mopac_example_module ()
{
status_descr_c status;
/*
* Register a new module, no preview or postview functions.
*/
module_register(MODULE_NAME, 0, 0, 0, &status);
/*
* Add the module to the "Modules" menu.
*/
discipline_add_module(BIOCHEM, MODULE_NAME, 0, 0, &status);
/*
* Open the module.
*/
module_open(MODULE_NAME);
/*
* Define the pulldown.
*/
menu_new(PULLDOWN_NAME,0);
/*
* Define the command.
*/
menu_add_cmd(PULLDOWN_NAME, COMMAND_NAME, do_my_mopac);
/*
* Use a molecule name-like parameter.
*/
param_new(PARAMETER_NAME, tident);
cmd_use_insight_param(COMMAND_NAME, PULLDOWN_NAME,
MOLECULE_NAME, PARAMETER_NAME, &status);
/*
* Put the parameter block over on the side.
*/
cmd_set_sideblock( PULLDOWN_NAME,COMMAND_NAME, 1);
/*
* Close the module.
*/
module_close(MODULE_NAME);
/*
* Make the menu.
*/
module_gen_menus(MODULE_NAME);
}
/******************************************************************************
* DO_MY_MOPAC
*
* Perform minimization on the specified molecule using mopac.
*
* This function gets called when the execute button in the parameter
* block has been pressed.
*/
static boolean_c do_my_mopac(
char *c,
char *p,
int origin
)
{
long_string_c cmd;
int i, len;
status_descr_c status;
process_c process;
short_string_c molecule;
mol_c mol;
base_object_c bobj;
monomer_c monomer;
atom_c atom;
fetch_c f;
boolean_c return_status = FALSE;
/*
* Get the molecule name that the user specified.
*/
if (param_get_ident_scope( p,c, PARAMETER_NAME, molecule)){
/*
* Execute the "put mopac" command. This will create the
* input file for the mopac job.
*/
str_to_lower_case(molecule, &status);
sprintf(cmd, "Put Molecule mopac %s %s", molecule, molecule);
cmd_execute(cmd);
/*
* Start up the mopac process. The mopac program will need
* the molecule name to be in lower case.
*/
sprintf(cmd, "%s/%s/biosym_exe/mopac %s",
getenv("BIOSYM"),
getenv("BIOSYM_PLATFORM"), molecule);
/*
* Fetch the base molecule, it will be passed to the
* callback function.
*/
fetch_init_insight(&f, molecule, &status);
if (system_fetch_base_object(g_system, &bobj, &f, &status)){
/*
* Start the background job.
*/
if (process_new_sync(&process, cmd, read_in_mopac, (long)bobj,
0, &status)) {
return_status = TRUE;
}
else {
message_print_error("Process creation failed.",
"Attempt to create mopac background job failed.",
&status);
}
}
fetch_end(&f, &status);
}
return(return_status);
}
/******************************************************************************
* READ_IN_MOPAC
*
* Read in the mopac output file.
*
* This completion function gets called automatically when the mopac job
* is finished.
*/
static boolean_c read_in_mopac(
long mol_long,
int job_status
)
{
status_descr_c status;
FILE *fp;
mol_c mol;
long_string_c file_name,
mol_name;
boolean_c return_status = FALSE;
/* Output a message to the info window/textport that the job
* is done.
*/
message_print_info("Mopac job done, status: %d\n", &status, job_status);
/*
* Read in the mopac file.
*/
mol = (mol_c) mol_long;
mol_get_name(mol, mol_name, &status);
str_to_lower_case(mol_name, &status);
sprintf(file_name, "%s.arc", mol_name);
if (file_open_by_name(&fp, NULL, file_name, "r", &status)){
/*
* Adjust the atom coordinates.
*/
mol_set_atoms_mopac_file(mol, fp, &status);
/*
* Redraw the screen so we can view the results.
*/
mol_rebuild_display(mol, &status);
system_draw(g_system, &status);
fclose(fp);
return_status = TRUE;
} else {
message_print_error("Could not open mopac file.",
"Attempt to open mopac background job output file failed.",
&status);
}
return(return_status);
}
/*
* Sample Distributed Chembench client.
*
* This program takes three command line arguments:
* client_example <server hostname> <atom1> <atom2>
*
* <server hostname> is the name of the Silicon Graphics workstation
* on which the Distributed Chembench server (Insight II) is running.
*
* <atom1> and <atom2> are two atom specifications of the form
* mol:monomer:atom.
*
* This program computes and displays the distance (in Angstroms)
* between the two atoms. If the atoms are bonded to each other,
* it then adds one angstrom to their bond length.
*
* This demonstrates a computation which is based on the molecular model
* maintained on the server and then modification of that model.
*
* To use this example file, first name it client_example.c.
*
* For example,
* 1) Start the server with the "insightII" command.
* 2) Enter the "get pdb 1crn.brk crn" command to retrieve a molecule.
* 3) Enter: dcb_run_client "client_example myiris CRN:1:CA CRN:1:N"
*
* Where myiris is the host name of the machine running Insight II.
*
* This approach could be used to create the user interface to a command
* with a BCL macro, which then uses the dcb_run_client command to
* execute the command in the client.
*
* Alternatively, the client could be started programatically from
* Insight II. For example, the following code, when linked into
* insightII using Open Interface, could be used to invoke the client,
* then go into server mode, thus replacing step 3 above:
*
* process_run_dcb_client("client_example myiris crn:1:ca crn:1:n", &s);
*
* You'll find an example of this programmatic approach in
* $BIOSYM_ROOT/$BIOSYM_CONTEXT/source/oi/oilib/atom_example.c.
*
* The makefile for making this client example is in the same directory
* and is called Makefile_dcb_irix6(or Makefile_dcb_irix5, depending on which
* version of the operating system that one has.
*
Here are a few tips for usage of distributed chembench.
1) Debugging.
Both and edge and dbx have multi-process debugging capabilities.
There is a chapter on this topic in your dbx users's reference
manual.
Alternatively, you can use an approach of running the client
in a separate shell. To use this technique:
a) Put insight into server mode with the "dcb_server_mode_on"
command. Insight will now wait for a client to request
a connection.
b) Go to a shell window and execute your client program.
For example, the text_edit client can be invoked with
a command like:
> client_example myiris CRN:1:CA CRN:1:N
If you want to debug the client, run it under dbx or
edge. For example:
> dbx client_example
(dbx) run myiris CRN:1:CA CRN:1:N
c) When the client calls system_end_dcb(), insight will come
back to the command prompt.
2) Getting insight out of server mode.
If your client fails to call system_end_dcb() (For example, if a bug
causes it to crash before it reaches that point), insight will be
left in server mode. To relinquish control of insight in order to
get the command prompt back, run a client which consists of nothing
but a call to system_new_dcb() and system_end_dcb(). That will
put insight back into interactive mode.
3) Error reporting
There is error reporting support for a uif written in BCL which
executes a command as a DCB client, although it is limited. The
dcb_run_client command returns the exit status of the client. You can
use this status code to indicate that an error occured. The
message_print_error command may then be used to display a standard red
box/black box error message. message_print_error takes two
long_string arguments: the first is displayed in the red box, the
second is displayed in the black box. For example, if the client
exits with the following line of code in an error condition:
exit(7);
the following BCL code may be used to report an error in this situation:
myint = {dcb_run_client my_client}
if ($myint == 7)
message_print_error "This command failed." "For a good reason."
end
*
*/
#include "system.h"
#include "mol.h"
#include <math.h>
main(
int argc,
char *argv[]
)
{
double d, dx, dy, dz;
bond_c bond;
mol_c mol;
monomer_c monomer;
atom_c atom1, atom2;
fetch_c f;
status_descr_c s;
boolean_c bonded;
coord_c c1, c2;
if (argc < 2) {
fprintf(stderr, "Usage: %s hostname atom1 atom2\n", argv[0]);
exit(1);
}
/*
* Connect to the server.
*/
system_new_dcb(&g_system, argv[1], &s);
/*
* Find the two atoms.
*/
if (system_find_atom(g_system, argv[2], &mol, &monomer, &atom1, &s)){
if (system_find_atom(g_system, argv[3], &mol, &monomer, &atom2, &s)){
/*
* Get their coordinates and compute the distance.
*/
atom_get_coord(atom1, &c1, &s);
atom_get_coord(atom2, &c2, &s);
dx = c2.x - c1.x;
dy = c2.y - c1.y;
dz = c2.z - c1.z;
d = fabs(sqrt(dx*dx + dy*dy + dz*dz));
printf("Distance: %f\n", d);
/*
* If they're bonded, add an angstrom to the bond length.
*/
atom_find_bond(atom1, atom2, &bonded, &bond, &s);
if (bonded){
bond_set_length(bond, d + 1.0, &s);
mol_rebuild_display(mol, &s);
system_draw(g_system, &s);
}
}
}
/*
* Relinquish control of the server.
*/
system_end_dcb(g_system, &s);
}