Content-Type: text/html ../example/awtype.c
   1: /*  This program is a minor derivative of the amw.c program distributed with
   2:  *  the CEX distribution.  It has been changed to compute an awtype property for
   3:  *  each atom which included the average atomic weight for the atom and all
   4:  *  attached hydrogens.  This is attached to each atom and output as a tuple
   5:  *  for use in the DockIt example scoring function program.  This program
   6:  *  illustrates, in a simple way, the atom type assignment which must be
   7:  *  done for each ligand and receptor atom in the CEX input stream, prior
   8:  *  to DockIt being run.
   9:  */
  11: /*  The original header for the program follows: */
  12: /*****************************************************************************
  13: *  amw.c -- CEX average molecular weight generator
  14: *----------------------------------------------------------------------------
  15: *  Contributing author and institution: Dave Weininger, Daylight CIS, Inc.
  16: *
  17: *  This source code is contributed to the public domain and may be freely
  18: *  copied and redistributed for research, profit, fun or any other reason,
  19: *  with these restrictions: (1) unmodified or functionally equivalent code
  20: *  derived from CX code must contain this notice, (2) all derived code must
  21: *  acknowledge the author and institution, and (3) the functional definition
  22: *  of symbols starting CX_ or cx_ may not be changed (if you need to change
  23: *  a function, CHANGE THE NAME: prefixes CU_ and cu_ are suggested).
  24: *****************************************************************************/
  26: 
  27: #include <string.h> 
  28: #include <stdlib.h> 
  29: #include <stdio.h> 
  30: 
  31: #include "cx.h" 
  32: #include "cx_molecule.h" 
  33: 
  34: #define MX_ELEM 105 
  35: 
  36: /*** aaw -- average atomic weight data ***/
  37: 
  38: static double aaw[MX_ELEM + 1] = {
  39:    0.000, 1.008, 4.0026, 6.94, 9.01218, 10.81, 12.011, 14.0067, 15.9994,
  40:    18.99846, 20.17, 22.98977, 24.305, 26.9815, 28.086, 30.9738, 32.06,
  41:    35.453, 39.948, 39.1, 40.08, 44.9559, 47.9, 50.941, 51.996, 54.938,
  42:    55.847, 58.9332, 58.71, 63.543, 65.38, 69.72, 72.59, 74.9216, 78.96,
  43:    79.904, 83.8, 85.467, 87.62, 88.9059, 91.22, 92.9064, 95.94, 98.9062,
  44:    101.07, 102.9055, 106.4, 107.868, 112.4, 114.82, 118.69, 121.75, 127.6,
  45:    126.9045, 131.3, 132.9055, 137.34, 138.9055, 140.12, 140.9077, 144.24,
  46:    145., 150.4, 151.96, 157.25, 158.9254, 162.5, 164.9303, 167.26, 168.9342,
  47:    173.04, 174.97, 178.49, 180.947, 183.85, 186.2, 190.2, 192.22, 195.09,
  48:    196.9665, 200.59, 204.37, 207.2, 208.9806, 209., 210., 222., 223., 226.,
  49:    227., 232.0381, 231.0359, 238.029, 237.0408, 244., 243., 247., 247.,
  50:    251., 254.09, 257.08, 258.098, 259.10, 260.1, 261.1, 262.11
  51: };
  52: 
  53: /*** prec -- precision, as places past decimal point ***/
  54: 
  55: static int prec[MX_ELEM + 1] = { 6,
  56:    3,4,2,5,2,3,4,4,5,2,5,3,4,3,4,2,3,3,1,2,4,1,3,3,3,3,4,2,3,2,2,2,4,2,3,
  57:    1,3,2,4,2,4,2,4,2,4,1,3,1,2,2,2,1,4,1,4,2,4,2,4,2,0,1,2,2,4,1,4,2,4,2,
  58:    2,2,3,2,1,1,2,2,4,2,2,1,4,0,0,0,0,0,0,4,4,3,4,0,0,0,0,0,2,2,3,2,1,1,2
  59: };
  60:   
  61: /*** Handy macro. ***/
  62: 
  63: #define NOTE(msg)  cx_error_save(msg, CX_ERR_NOTE,  *argv) 
  64: #define FATAL(msg) cx_error_save(msg, CX_ERR_FATAL, *argv) 
  65: 
  66: /*============================================================================
  67:  *  amwof() -- calculate average molecular weight of molecule
  68:  *
  69:  *  This function ignores atomic mass and accounts for implicit hydrogens.
  70:  */
  72: 
  73: static void amwof(cx_Object mol)
  74: {
  75:    static char buf[20];
  76:    int         atno, imph, p = 6;
  77:    double      amw = 0.0;
  78:    cx_Object   atom, atoms = cx_stream(mol, CX_OB_ATOM);
  79: 
  80:    /*** Loop over atoms, adding up molecular weight. ***/
  81: 
  82:    while (NULL != (atom = cx_next(atoms))) {
  83:      atno = cx_iprop(atom, "atomic number");
  84: 
  85:      /*** Get atomic weight of each heavy atom, track precision. ***/
  86: 
  87:      if (0 < atno && MX_ELEM >= atno) {
  88:         amw = aaw[atno];
  89:         p    = CX_MIN(p, prec[atno]);
  90:      }
  91: 
  92:      /*** Add atomic weight of non-explicit hydrogens. ***/
  93: 
  94:      if (0 < (imph = cx_iprop(atom, "implicit hcount"))) {
  95:         amw += imph * aaw[1];
  96:         p    = CX_MIN(p, prec[1]);
  97:      }
  98:      sprintf(buf, "%.*f", p, amw);
  99:      cx_set_sprop(atom, "awtype", buf);
 100:    }
 101:    cx_destroy(atoms);
 102: 
 103:    /*** Write ave mol wt to correct precision and return it. ***/
 104: 
 105:    return ;
 106: }
 107: 
 108: /*============================================================================
 109:  *  main() for amw
 110:  */
 112: 
 113: int main(int argc, char **argv)
 114: {
 115:    cx_Object ob, ins, outs;
 116:    cx_Object  dt, atuple;
 117: 
 118:    /*** This program takes no options -- show usage if any specified. ***/
 119: 
 120:    if (1 < argc) {
 121:       FATAL("This program doesn't accept options or arguments.");
 122:       NOTE ("usage:   cex input | awtype | cex output"            );
 123:       NOTE ("Adds awtype (ave atomic wt) to atoms in molecules on cex stream" );
 124:       cx_error_spew(stderr, NULL);
 125:       exit(0);
 126:    }
 127: 
 128:    /*** Initialize molecule package. ***/
 129: 
 130:    cx_molecule_pkg();
 131: 
 132:    /*** Create AMW datatype in default datatype table. ***/
 133:    if (NULL == (dt = cx_tag2datatype(NULL, "AWTYPE")))
 134:      dt = cx_create_datatype(NULL, "AWTYPE", "awtype",
 135: 			     "AW ligand atom type", "1A", "STRING", 
 136: 			     "AW ligand atom type");
 137: 
 138:    /*** Create input and output streams. ***/
 139: 
 140:    ins  = cx_create_iostream("-", CX_IO_READ );
 141:    outs = cx_create_iostream("-", CX_IO_WRITE);
 142: 
 143:    /*** Loop over objects on standard input and output streams. ***/
 144: 
 145:    while (NULL != (ob = cx_next(ins))) {
 146: 
 147:       /*** Calculate AMW for molecules, add as property. ***/
 148: 
 149:      if (CX_OB_MOLECULE == cx_type(ob)) {
 150:        atuple = cx_create_atomtuple(ob, "awtype");
 151:        cx_set_datatype(atuple, cx_tag2datatype(NULL, "AWTYPE"));
 152:        
 153:        amwof(ob);
 154:      }
 155: 
 156:      /*** Send object to stdout. ***/
 157: 
 158:      cx_append(outs, ob);
 159:      
 160:      /*** Clean up. ***/
 161:      
 162:      cx_error_spew(stderr, NULL);
 163:      cx_destroy(ob);
 164:    }
 165:    
 166:    /*** DON'T: Transmit remaining datatypes. (This was only a test!) ***/
 167:    
 168:    /* cx_append(outs, cx_default_datatypetable()); */
 169:    
 170:    /*** Clean up, close files, and exit with 0. ***/
 171:    
 172:    cx_error_spew(stderr, NULL);
 173:    cx_destroy(outs);
 174:    cx_cleanup();
 175:    return 0;
 176: }
 177: