1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
#!/usr/bin/python
#
# International Chemical Identifier (InChI)
# Version 1
# Software version 1.02
# November 30, 2008
# Developed at NIST
#
# The InChI library and programs are free software developed under the
# auspices of the International Union of Pure and Applied Chemistry (IUPAC);
# you can redistribute this software and/or modify it under the terms of
# the GNU Lesser General Public License as published by the Free Software
# Foundation:
# http://www.opensource.org/licenses/lgpl-license.php
#
"""
Interface to INCHI library (used by InChI generation example)
The implementation is very 'light' and is provided for
illustrative purposes only.
"""
import os
import sys
import string
from ctypes import *
PYINCHI_MAXVAL = 20
PYINCHI_ATOM_EL_LEN = 6
PYINCHI_NUM_H_ISOTOPES = 3
#this flag means isotopic shift relative to avg. atw, not abs. isotopic mass
PYINCHI_ISOTOPIC_SHIFT_FLAG = 10000
##########################################################
# 0D - S T E R E O (if no coordinates given)
##########################################################
class inchi_Stereo0D(Structure):
_fields_ = [("neighbor", c_short * 4), # 4 atoms always
("central_atom", c_short), # central tetrahedral atom or a central */
# atom of allene; otherwise NO_ATOM */
("type", c_byte), # inchi_StereoType0D
("parity", c_byte)] # inchi_StereoParity0D: may be a combination of two parities: */
# ParityOfConnected | (ParityOfDisconnected << 3), see Note above */
def dump(self):
print "\tDump of inchi_Stereo0D structure"
print '\t\t neighbor: ',
for nbr in self.neighbor:
print nbr,
print
print '\t\t central_atom: ', self.central_atom
print '\t\t type: ', self.type
print '\t\t parity: ', self.parity
##########################################
# inchi_Atom
##########################################
class inchi_Atom(Structure):
_fields_ = [("x", c_double), # atom coordinates
("y", c_double),
("z", c_double),
# connectivity
("neighbor", c_short * PYINCHI_MAXVAL), # adjacency list: ordering numbers of the adjacent atoms, >= 0
("bond_type", c_byte * PYINCHI_MAXVAL), # inchi_BondType
# 2D stereo
("bond_stereo", c_byte * PYINCHI_MAXVAL), # inchi_BondStereo2D; negative if the sharp end points to another atom
# other atom properties
("elname", c_byte * PYINCHI_ATOM_EL_LEN), # zero-terminated chemical element name: "H", "Si", etc.
("num_bonds", c_short ), # number of neighbors, bond types and bond stereo in the adjacency list
("num_iso_H", c_byte * (PYINCHI_NUM_H_ISOTOPES+1)), # implicit hydrogen atoms
# [0]: number of implicit non-isotopic H
# (exception: num_iso_H[0]=-1 means INCHI adds implicit H automatically),
# [1]: number of implicit isotopic 1H (protium),
# [2]: number of implicit 2H (deuterium),
# [3]: number of implicit 3H (tritium)
("isotopic_mass", c_short ), # 0 => non-isotopic; isotopic mass or 10000 + mass - (average atomic mass)
("radical", c_byte ), # inchi_Radical
("charge", c_byte )] # positive or negative; 0 => no charge
def fdump(self, fw):
fw.write('\t{\t --- Dump of inchi_Atom structure ---\n')
s = ""
for sy in self.elname:
s = s + chr(sy)
fw.write('\t\t element: %-s \n' % s )
fw.write('\t\t charge: %-d radical: %-d isotopic_mass: %-d\n' %
(self.charge, self.radical, self.isotopic_mass) )
fw.write('\t\t num_bonds: %-d\n' % self.num_bonds)
fw.write('\t\t neighbor: ')
for nbr in self.neighbor:
fw.write(' %-d' % nbr)
fw.write('\n')
fw.write('\t\t bond_types: ')
for bt in self.bond_type:
fw.write(' %-d ' % bt)
fw.write('\n')
fw.write('\t\t bond_stereos: ')
for bs in self.bond_stereo:
fw.write(' %-d' % bs)
fw.write('\n')
fw.write('\t\t num_iso_H: ')
for ni in self.num_iso_H:
fw.write(' %-d' % ni)
fw.write('\n\t} \n')
def dump(self):
self.fdump(sys.stdout)
##########################################
# Structure -> InChI, GetINCHI()
##########################################
class inchi_Input(Structure):
# the caller is responsible for the data allocation and deallocation
_fields_ = [("atom", POINTER(inchi_Atom)), # actually, pointer to array of inchi_Atom pointers
("stereo0D", POINTER(inchi_Stereo0D)), # actually, pointer to array of inchi_Stereo0D
("szOptions", c_char_p), # InChI options: space-delimited; each is preceded by '/' or '-'
("num_atoms", c_int), #c_short), # number of atoms in the compound < 1024
("num_stereo0D", c_short)] # number of 0D stereo elements
# /* InChI -> Structure, GetStructFromINCHI() */
# typedef struct tagINCHI_InputINCHI {
# /* the caller is responsible for the data allocation and deallocation */
# char *szInChI; /* InChI ASCIIZ string to be converted to a strucure */
# char *szOptions; /* InChI options: space-delimited; each is preceded by */
# /* '/' or '-' depending on OS and compiler */
# } inchi_InputINCHI;
##########################################################
# InChI -> Structure, GetStructFromINCHI()
##########################################################
class inchi_InputINCHI(Structure):
_fields_ = [("szInChI", c_char_p), # InChI ASCIIZ string to be converted to a strucure
("szOptions", c_char_p)] # InChI options: space-delimited; each is preceded by
# '/' or '-' depending on OS and compiler */
# the caller is responsible for the data allocation and deallocation
##########################################################################
# inchi_Output
##########################################################################
class inchi_Output(Structure):
# zero-terminated C-strings allocated by GetINCHI()
# to deallocate all of them call FreeINCHI() (see below)
_fields_ = [("szInChI", POINTER(c_char) ), # c_char_p
("szAuxInfo", POINTER(c_char) ),
("szMessage", POINTER(c_char) ),
("szLog", POINTER(c_char) ) ] # c_char_p)]
def dump(self):
print "\tDump of inchi_Output structure"
print '\t\t',self.szInChI
print '\t\t',self.szAuxInfo
print '\t\t',self.szMessage
print '\t\t',self.szLog
##########################################################################
# InChI -> Structure
##########################################################################
#class inchi_OutputStruct(Structure):
# # 4 pointers are allocated by GetStructFromINCHI()
# # to deallocate all of them call FreeStructFromINCHI()
# _fields_ = [("atom", c_long), # actually, pointer to array of inchi_Atom
# ("stereo0D", c_long), # actually, pointer to array of inchi_Stereo0D
#
# _fields_ = [("atom", POINTER(inchi_Atom)), # actually, pointer to array of inchi_Atom
# ("stereo0D", POINTER(inchi_Stereo0D)), # actually, pointer to array of inchi_Stereo0D
#
#
# ("szMessage", c_char_p), # Error/warning ASCIIZ message
# ("szLog", c_char_p), # log-file ASCIIZ string, contains a human-readable list
# # of recognized options and possibly an Error/warning message
#
#
# ("num_stereo0D", c_short)] # number of 0D stereo elements
#
#
#
# typedef struct tagINCHI_OutputStruct {
# inchi_Atom *atom; /* array of num_atoms elements */
# inchi_Stereo0D *stereo0D; /* array of num_stereo0D 0D stereo elements or NULL */
# AT_NUM num_atoms; /* number of atoms in the structure < 1024 */
# AT_NUM num_stereo0D; /* number of 0D stereo elements */
# char *szMessage; /* Error/warning ASCIIZ message */
# char *szLog; /* log-file ASCIIZ string, contains a human-readable list */
# /* of recognized options and possibly an Error/warning message */
# unsigned long WarningFlags[2][2]; /* warnings, see INCHIDIFF in inchicmp.h */
# /* [x][y]: x=0 => Reconnected if present in InChI otherwise Disconnected/Normal
# x=1 => Disconnected layer if Reconnected layer is present
# y=1 => Main layer or Mobile-H
# y=0 => Fixed-H layer
# */
# }inchi_OutputStruct;
|