Open Interface



2       Examples

This chapter contains examples of Open Interface code, Makefiles, BCL examples (for performance comparison), and instructions for trying the examples on your computer.

Example 1. Properties

The property example creates a new functional monomer property called HW_hydrophobicity. After it is compiled and linked, you will be able to use this new property in Insight II in any command that accepts monomer properties, for example:

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.

Example 2. Chembench/Workbench commands

The oi_customize.c file contains examples of two commands added to Insight using Workbench for the user interface and Chembench for the command execution.

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.

Example 3.DCB commands

This example, client_example.cexample, demonstrates usage of Distributed Chembench to implement a command in a program which is separately executed from Insight II. Note that the code of the client program is very similar to a conventional Chembench-based command. The only difference is the call to system_new_dcb() to initialize the connection between the client and the server and system_end_dcb() to terminate it.

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.


Instructions

Follow these steps to create a new DSO library called libuser.so containing custom commands and properties for Insight II. The DCB example is completely self contained, see the file client_example.cexample for instructions.

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

  1. Study the information about the examples on the following pages, including the Makefile and source code.

  2. Copy the source files to an empty directory.
    C sources found in: $BIOSYM_ROOT/$BIOSYM_CONTEXT/source/oi/oilib
    oi_customize.c
    prop_example.c
    atom_example.c
    mopac_example.c
    client_example.cexample
    Makefile_irix6 (or Makefile_irix5, according to your operating system)

    BCL files found in: $BIOSYM_ROOT/$BIOSYM_CONTEXT/gifts/insight
    hydro.bcl
    flex.bcl

  3. Rename Makefile_irix6 to Makefile.

  4. Edit the oi_customize.c file, un-comment the oi_customize() function.

  5. Compile the examples using the UNIX "make" command.

  6. Update your LD_LIBRARY_PATH, prepend the current directory as in:


	setenv LD_LIBRARY_PATH .\:$LD_LIBRARY_PATH


  1. Start Insight II.

  2. Enter the new command or use the new property in an existing command.

  3. If BCL macros are provided for comparison, "Source" the macro and execute the command or use the new property that the macro defines.

  4. Customize the examples.


Makefile

This is the Makefile for compiling the examples on SGI running IRIX 6.


# 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
#


Source Code

Note that some formatting changes were done to make the text fit in this document. Some unused functions in the source have been removed from this document.

prop_example.c


/******************************************************************************
 *+ 
 * 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);
}
    



hydro.bcl


# 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

flex.bcl


# 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



/******************************************************************************
 *+ 
 * 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, &degrees))
	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



/******************************************************************************
 *+ 
 * 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);
}



client_example.cexample


/*
 * 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);
    
}






Last updated October 13, 1997 at 02:51PM PDT.
Copyright © 1997, Molecular Simulations, Inc. All rights reserved.