rino 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +44 -0
- data/Rakefile +123 -0
- data/ext/extconf.rb +26 -0
- data/ext/ruby_inchi_main.so +0 -0
- data/ext/src/aux2atom.h +2786 -0
- data/ext/src/comdef.h +148 -0
- data/ext/src/e_0dstereo.c +3014 -0
- data/ext/src/e_0dstereo.h +31 -0
- data/ext/src/e_comdef.h +57 -0
- data/ext/src/e_ctl_data.h +147 -0
- data/ext/src/e_ichi_io.c +498 -0
- data/ext/src/e_ichi_io.h +40 -0
- data/ext/src/e_ichi_parms.c +37 -0
- data/ext/src/e_ichi_parms.h +41 -0
- data/ext/src/e_ichicomp.h +50 -0
- data/ext/src/e_ichierr.h +40 -0
- data/ext/src/e_ichimain.c +593 -0
- data/ext/src/e_ichisize.h +43 -0
- data/ext/src/e_inchi_atom.c +75 -0
- data/ext/src/e_inchi_atom.h +33 -0
- data/ext/src/e_inpdef.h +41 -0
- data/ext/src/e_mode.h +706 -0
- data/ext/src/e_mol2atom.c +649 -0
- data/ext/src/e_readinch.c +58 -0
- data/ext/src/e_readmol.c +54 -0
- data/ext/src/e_readmol.h +180 -0
- data/ext/src/e_readstru.c +251 -0
- data/ext/src/e_readstru.h +33 -0
- data/ext/src/e_util.c +284 -0
- data/ext/src/e_util.h +61 -0
- data/ext/src/extr_ct.h +251 -0
- data/ext/src/ichi.h +206 -0
- data/ext/src/ichi_bns.c +7999 -0
- data/ext/src/ichi_bns.h +231 -0
- data/ext/src/ichican2.c +5000 -0
- data/ext/src/ichicano.c +2195 -0
- data/ext/src/ichicano.h +49 -0
- data/ext/src/ichicans.c +1625 -0
- data/ext/src/ichicant.h +379 -0
- data/ext/src/ichicomn.h +260 -0
- data/ext/src/ichicomp.h +50 -0
- data/ext/src/ichidrp.h +119 -0
- data/ext/src/ichierr.h +124 -0
- data/ext/src/ichiisot.c +101 -0
- data/ext/src/ichilnct.c +286 -0
- data/ext/src/ichimain.h +132 -0
- data/ext/src/ichimak2.c +1189 -0
- data/ext/src/ichimake.c +3812 -0
- data/ext/src/ichimake.h +205 -0
- data/ext/src/ichimap1.c +851 -0
- data/ext/src/ichimap2.c +2856 -0
- data/ext/src/ichimap4.c +1609 -0
- data/ext/src/ichinorm.c +741 -0
- data/ext/src/ichinorm.h +67 -0
- data/ext/src/ichiparm.c +45 -0
- data/ext/src/ichiparm.h +1441 -0
- data/ext/src/ichiprt1.c +3612 -0
- data/ext/src/ichiprt2.c +1511 -0
- data/ext/src/ichiprt3.c +3011 -0
- data/ext/src/ichiqueu.c +1003 -0
- data/ext/src/ichiring.c +326 -0
- data/ext/src/ichiring.h +49 -0
- data/ext/src/ichisize.h +35 -0
- data/ext/src/ichisort.c +539 -0
- data/ext/src/ichister.c +3538 -0
- data/ext/src/ichister.h +35 -0
- data/ext/src/ichitaut.c +3843 -0
- data/ext/src/ichitaut.h +387 -0
- data/ext/src/ichitime.h +74 -0
- data/ext/src/inchi_api.h +670 -0
- data/ext/src/inchi_dll.c +1480 -0
- data/ext/src/inchi_dll.h +34 -0
- data/ext/src/inchi_dll_main.c +23 -0
- data/ext/src/inchi_dll_main.h +31 -0
- data/ext/src/inpdef.h +328 -0
- data/ext/src/lreadmol.h +1246 -0
- data/ext/src/mode.h +706 -0
- data/ext/src/ruby_inchi_main.c +558 -0
- data/ext/src/runichi.c +4179 -0
- data/ext/src/strutil.c +3861 -0
- data/ext/src/strutil.h +182 -0
- data/ext/src/util.c +1130 -0
- data/ext/src/util.h +85 -0
- data/lib/clean_tempfile.rb +220 -0
- data/lib/rino.rb +111 -0
- data/test/test.rb +386 -0
- metadata +130 -0
data/ext/src/util.h
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
/*
|
2
|
+
* International Union of Pure and Applied Chemistry (IUPAC)
|
3
|
+
* International Chemical Identifier (InChI)
|
4
|
+
* Version 1
|
5
|
+
* Software version 1.00
|
6
|
+
* April 13, 2005
|
7
|
+
* Developed at NIST
|
8
|
+
*/
|
9
|
+
|
10
|
+
#ifndef __UTIL_H__
|
11
|
+
#define __UTIL_H__
|
12
|
+
|
13
|
+
#include "inpdef.h"
|
14
|
+
|
15
|
+
/* BILLY 8/6/04 */
|
16
|
+
#ifndef INCHI_ALL_CPP
|
17
|
+
#ifdef __cplusplus
|
18
|
+
extern "C" {
|
19
|
+
#endif
|
20
|
+
#endif
|
21
|
+
|
22
|
+
int get_atw(const char *elname);
|
23
|
+
int get_atw_from_elnum( int nAtNum );
|
24
|
+
int get_num_H (const char* elname, int inp_num_H, S_CHAR num_iso_H[], int charge, int radical,
|
25
|
+
int chem_bonds_valence, int atom_input_valence, int bAliased, int bDoNotAddH, int bHasMetalNeighbor );
|
26
|
+
int extract_ChargeRadical( char *elname, int *pnRadical, int *pnCharge );
|
27
|
+
int extract_H_atoms( char *elname, S_CHAR num_iso_H[] );
|
28
|
+
int normalize_name( char* name );
|
29
|
+
|
30
|
+
int mystrncpy(char *target,const char *source,unsigned maxlen);
|
31
|
+
char* LtrimRtrim( char *p, int* nLen );
|
32
|
+
char* fgets_up_to_lf( char* line, int line_len, FILE* inp );
|
33
|
+
void remove_trailing_spaces( char* p );
|
34
|
+
void remove_one_lf( char* p);
|
35
|
+
void mystrrev( char *p );
|
36
|
+
#ifndef INCHI_LIBRARY
|
37
|
+
int my_fgets( char *szLine, int len, FILE *f, int *bTooLongLine );
|
38
|
+
int my_fgetsTab( char *szLine, int len, FILE *f, int *bTooLongLine );
|
39
|
+
int my_fgetsTab1( char *szLine, int len, FILE *f, int *bTooLongLine );
|
40
|
+
#endif
|
41
|
+
int my_fgetsUpToLfOrTab( char *szLine, int len, FILE *f );
|
42
|
+
|
43
|
+
|
44
|
+
AT_NUMB *is_in_the_list( AT_NUMB *pathAtom, AT_NUMB nNextAtom, int nPathLen );
|
45
|
+
int get_periodic_table_number( const char* elname );
|
46
|
+
int is_el_a_metal( int nPeriodicNum );
|
47
|
+
int get_el_valence( int nPeriodicNum, int charge, int val_num );
|
48
|
+
int get_unusual_el_valence( int nPeriodicNum, int charge, int radical, int bonds_valence, int num_H, int num_bonds );
|
49
|
+
int detect_unusual_el_valence( int nPeriodicNum, int charge, int radical, int bonds_valence, int num_H, int num_bonds );
|
50
|
+
int needed_unusual_el_valence( int nPeriodicNum, int charge, int radical, int bonds_valence, int num_H, int num_bonds );
|
51
|
+
int get_el_type( int nPeriodicNum );
|
52
|
+
int get_el_number( const char* elname );
|
53
|
+
int do_not_add_H( int nPeriodicNum );
|
54
|
+
int GetElementFormulaFromAtNum(int nAtNum, char *szElement );
|
55
|
+
int MakeRemovedProtonsString( int nNumRemovedProtons, NUM_H *nNumExchgIsotopicH, NUM_H *nNumRemovedProtonsIsotopic,
|
56
|
+
int bIsotopic, char *szRemovedProtons, int *num_removed_iso_H );
|
57
|
+
|
58
|
+
/* ion pairs and fixing bonds */
|
59
|
+
int num_of_H( inp_ATOM *at, int iat );
|
60
|
+
int has_other_ion_neigh( inp_ATOM *at, int iat, int iat_ion_neigh, const char *el, int el_len );
|
61
|
+
int has_other_ion_in_sphere_2(inp_ATOM *at, int iat, int iat_ion_neigh, const char *el, int el_len );
|
62
|
+
int nNoMetalNumBonds( inp_ATOM *at, int at_no );
|
63
|
+
int nNoMetalBondsValence( inp_ATOM *at, int at_no );
|
64
|
+
int nNoMetalNeighIndex( inp_ATOM *at, int at_no );
|
65
|
+
int nNoMetalOtherNeighIndex( inp_ATOM *at, int at_no, int cur_neigh );
|
66
|
+
int nNoMetalOtherNeighIndex2( inp_ATOM *at, int at_no, int cur_neigh, int cur_neigh2 );
|
67
|
+
|
68
|
+
|
69
|
+
/* IChICan2.c */
|
70
|
+
int SetBitFree( void );
|
71
|
+
|
72
|
+
void WriteCoord( char *str, double x );
|
73
|
+
|
74
|
+
|
75
|
+
extern int ERR_ELEM;
|
76
|
+
|
77
|
+
/* BILLY 8/6/04 */
|
78
|
+
#ifndef INCHI_ALL_CPP
|
79
|
+
#ifdef __cplusplus
|
80
|
+
}
|
81
|
+
#endif
|
82
|
+
#endif
|
83
|
+
|
84
|
+
#endif /* __UTIL_H__*/
|
85
|
+
|
@@ -0,0 +1,220 @@
|
|
1
|
+
# =================================
|
2
|
+
# Rino - The InChI Toolkit for Ruby
|
3
|
+
# =================================
|
4
|
+
#
|
5
|
+
# Project Info: http://rino.rubyforge.org
|
6
|
+
#
|
7
|
+
# Copyright (C) 2006 Richard L. Apodaca
|
8
|
+
#
|
9
|
+
# This library is free software; you can redistribute it and/or
|
10
|
+
# modify it under the terms of the GNU Lesser General Public
|
11
|
+
# License version 2.1 as published by the Free Software
|
12
|
+
# Foundation.
|
13
|
+
#
|
14
|
+
# This library is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
17
|
+
# Lesser General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU Lesser General Public
|
20
|
+
# License along with this library; if not, write to the Free
|
21
|
+
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
|
22
|
+
# Boston, MA 02111-1301, USA.
|
23
|
+
#
|
24
|
+
# This file originally appeared in the Ruby standard library
|
25
|
+
# as 'tempfile.rb' and has been modified as documented.
|
26
|
+
|
27
|
+
require 'delegate'
|
28
|
+
require 'tmpdir'
|
29
|
+
|
30
|
+
# A class for managing temporary files. This library is written to be
|
31
|
+
# thread safe.
|
32
|
+
# CleanTempfile is a slightly modified version of Tempfile in the standard
|
33
|
+
# Ruby library. Its open method opens the tempfile in write mode. This
|
34
|
+
# clears the contents of the previously written molfile which would
|
35
|
+
# otherwise be present in the standard Tempfile implementation.
|
36
|
+
class CleanTempfile < DelegateClass(File)
|
37
|
+
MAX_TRY = 10
|
38
|
+
@@cleanlist = []
|
39
|
+
|
40
|
+
# Creates a temporary file of mode 0600 in the temporary directory
|
41
|
+
# whose name is basename.pid.n and opens with mode "w+". A Tempfile
|
42
|
+
# object works just like a File object.
|
43
|
+
#
|
44
|
+
# If tmpdir is omitted, the temporary directory is determined by
|
45
|
+
# Dir::tmpdir provided by 'tmpdir.rb'.
|
46
|
+
# When $SAFE > 0 and the given tmpdir is tainted, it uses
|
47
|
+
# /tmp. (Note that ENV values are tainted by default)
|
48
|
+
def initialize(basename, tmpdir=Dir::tmpdir)
|
49
|
+
if $SAFE > 0 and tmpdir.tainted?
|
50
|
+
tmpdir = '/tmp'
|
51
|
+
end
|
52
|
+
|
53
|
+
lock = nil
|
54
|
+
n = failure = 0
|
55
|
+
|
56
|
+
begin
|
57
|
+
Thread.critical = true
|
58
|
+
|
59
|
+
begin
|
60
|
+
tmpname = File.join(tmpdir, make_tmpname(basename, n))
|
61
|
+
lock = tmpname + '.lock'
|
62
|
+
n += 1
|
63
|
+
end while @@cleanlist.include?(tmpname) or
|
64
|
+
File.exist?(lock) or File.exist?(tmpname)
|
65
|
+
|
66
|
+
Dir.mkdir(lock)
|
67
|
+
rescue
|
68
|
+
failure += 1
|
69
|
+
retry if failure < MAX_TRY
|
70
|
+
raise "cannot generate tempfile `%s'" % tmpname
|
71
|
+
ensure
|
72
|
+
Thread.critical = false
|
73
|
+
end
|
74
|
+
|
75
|
+
@data = [tmpname]
|
76
|
+
@clean_proc = Tempfile.callback(@data)
|
77
|
+
ObjectSpace.define_finalizer(self, @clean_proc)
|
78
|
+
|
79
|
+
@tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)
|
80
|
+
@tmpname = tmpname
|
81
|
+
@@cleanlist << @tmpname
|
82
|
+
@data[1] = @tmpfile
|
83
|
+
@data[2] = @@cleanlist
|
84
|
+
|
85
|
+
super(@tmpfile)
|
86
|
+
|
87
|
+
# Now we have all the File/IO methods defined, you must not
|
88
|
+
# carelessly put bare puts(), etc. after this.
|
89
|
+
|
90
|
+
Dir.rmdir(lock)
|
91
|
+
end
|
92
|
+
|
93
|
+
def make_tmpname(basename, n)
|
94
|
+
sprintf('%s%d.%d', basename, $$, n)
|
95
|
+
end
|
96
|
+
private :make_tmpname
|
97
|
+
|
98
|
+
# Opens or reopens the file with mode "w+", rather than
|
99
|
+
# "r+" as in tempfile.rb.
|
100
|
+
def open
|
101
|
+
@tmpfile.close if @tmpfile
|
102
|
+
|
103
|
+
# uses 'w+' instead of 'r+' as used in tempfile.rb
|
104
|
+
@tmpfile = File.open(@tmpname, 'w+')
|
105
|
+
@data[1] = @tmpfile
|
106
|
+
__setobj__(@tmpfile)
|
107
|
+
end
|
108
|
+
|
109
|
+
def _close # :nodoc:
|
110
|
+
@tmpfile.close if @tmpfile
|
111
|
+
@data[1] = @tmpfile = nil
|
112
|
+
end
|
113
|
+
protected :_close
|
114
|
+
|
115
|
+
# Closes the file. If the optional flag is true, unlinks the file
|
116
|
+
# after closing.
|
117
|
+
#
|
118
|
+
# If you don't explicitly unlink the temporary file, the removal
|
119
|
+
# will be delayed until the object is finalized.
|
120
|
+
def close(unlink_now=false)
|
121
|
+
if unlink_now
|
122
|
+
close!
|
123
|
+
else
|
124
|
+
_close
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Closes and unlinks the file.
|
129
|
+
def close!
|
130
|
+
_close
|
131
|
+
@clean_proc.call
|
132
|
+
ObjectSpace.undefine_finalizer(self)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Unlinks the file. On UNIX-like systems, it is often a good idea
|
136
|
+
# to unlink a temporary file immediately after creating and opening
|
137
|
+
# it, because it leaves other programs zero chance to access the
|
138
|
+
# file.
|
139
|
+
def unlink
|
140
|
+
# keep this order for thread safeness
|
141
|
+
begin
|
142
|
+
File.unlink(@tmpname) if File.exist?(@tmpname)
|
143
|
+
@@cleanlist.delete(@tmpname)
|
144
|
+
@data = @tmpname = nil
|
145
|
+
ObjectSpace.undefine_finalizer(self)
|
146
|
+
rescue Errno::EACCESS
|
147
|
+
# may not be able to unlink on Windows; just ignore
|
148
|
+
end
|
149
|
+
end
|
150
|
+
alias delete unlink
|
151
|
+
|
152
|
+
# Returns the full path name of the temporary file.
|
153
|
+
def path
|
154
|
+
@tmpname
|
155
|
+
end
|
156
|
+
|
157
|
+
# Returns the size of the temporary file. As a side effect, the IO
|
158
|
+
# buffer is flushed before determining the size.
|
159
|
+
def size
|
160
|
+
if @tmpfile
|
161
|
+
@tmpfile.flush
|
162
|
+
@tmpfile.stat.size
|
163
|
+
else
|
164
|
+
0
|
165
|
+
end
|
166
|
+
end
|
167
|
+
alias length size
|
168
|
+
|
169
|
+
class << self
|
170
|
+
def callback(data) # :nodoc:
|
171
|
+
pid = $$
|
172
|
+
lambda{
|
173
|
+
if pid == $$
|
174
|
+
path, tmpfile, cleanlist = *data
|
175
|
+
|
176
|
+
print "removing ", path, "..." if $DEBUG
|
177
|
+
|
178
|
+
tmpfile.close if tmpfile
|
179
|
+
|
180
|
+
# keep this order for thread safeness
|
181
|
+
File.unlink(path) if File.exist?(path)
|
182
|
+
cleanlist.delete(path) if cleanlist
|
183
|
+
|
184
|
+
print "done\n" if $DEBUG
|
185
|
+
end
|
186
|
+
}
|
187
|
+
end
|
188
|
+
|
189
|
+
# If no block is given, this is a synonym for new().
|
190
|
+
#
|
191
|
+
# If a block is given, it will be passed tempfile as an argument,
|
192
|
+
# and the tempfile will automatically be closed when the block
|
193
|
+
# terminates. In this case, open() returns nil.
|
194
|
+
def open(*args)
|
195
|
+
tempfile = new(*args)
|
196
|
+
|
197
|
+
if block_given?
|
198
|
+
begin
|
199
|
+
yield(tempfile)
|
200
|
+
ensure
|
201
|
+
tempfile.close
|
202
|
+
end
|
203
|
+
|
204
|
+
nil
|
205
|
+
else
|
206
|
+
tempfile
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
if __FILE__ == $0
|
213
|
+
# $DEBUG = true
|
214
|
+
f = Tempfile.new("foo")
|
215
|
+
f.print("foo\n")
|
216
|
+
f.close
|
217
|
+
f.open
|
218
|
+
p f.gets # => "foo\n"
|
219
|
+
f.close!
|
220
|
+
end
|
data/lib/rino.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# =================================
|
2
|
+
# Rino - The InChI Toolkit for Ruby
|
3
|
+
# =================================
|
4
|
+
#
|
5
|
+
# Project Info: http://rino.rubyforge.org
|
6
|
+
#
|
7
|
+
# Copyright (C) 2006 Richard L. Apodaca
|
8
|
+
#
|
9
|
+
# This library is free software; you can redistribute it and/or
|
10
|
+
# modify it under the terms of the GNU Lesser General Public
|
11
|
+
# License version 2.1 as published by the Free Software
|
12
|
+
# Foundation.
|
13
|
+
#
|
14
|
+
# This library is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
17
|
+
# Lesser General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU Lesser General Public
|
20
|
+
# License along with this library; if not, write to the Free
|
21
|
+
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
|
22
|
+
# Boston, MA 02111-1301, USA.
|
23
|
+
#
|
24
|
+
# Typical usage:
|
25
|
+
#
|
26
|
+
# reader = Rino::MolfileReader.new
|
27
|
+
# inchi = reader.read(IO.read('benzene.mol'))
|
28
|
+
#
|
29
|
+
# puts inchi -> 'InChI=1/C6H6/c1-2-4-6-5-3-1/h1-6H'
|
30
|
+
|
31
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "ext")
|
32
|
+
|
33
|
+
require 'tempfile'
|
34
|
+
require 'clean_tempfile'
|
35
|
+
require 'ruby_inchi_main'
|
36
|
+
|
37
|
+
module Rino
|
38
|
+
# Creates an InChI string from a molfile. This class coordinates the creation
|
39
|
+
# and deletion of temporary i/o files according to the rules used by Tempfile.
|
40
|
+
class MolfileReader
|
41
|
+
|
42
|
+
# Accepts the same options as the InChI command line
|
43
|
+
# software. See: http://wwmm.ch.cam.ac.uk/inchifaq/ and the
|
44
|
+
# InChI Technical Manual for an explanation of these options.
|
45
|
+
#
|
46
|
+
# Example:
|
47
|
+
#
|
48
|
+
# reader = Rino::MolfileReader.new
|
49
|
+
#
|
50
|
+
# reader.options << "-Compress"
|
51
|
+
attr_reader :options
|
52
|
+
|
53
|
+
def initialize
|
54
|
+
@in = CleanTempfile.new("inchi_input.mol")
|
55
|
+
@out = Tempfile.new("inchi_output.txt")
|
56
|
+
@log = Tempfile.new("inchi_log.txt")
|
57
|
+
@prob = Tempfile.new("inchi_problem.txt")
|
58
|
+
@main = Main.new
|
59
|
+
@options = Array.new
|
60
|
+
end
|
61
|
+
|
62
|
+
#Reads the specified molfile encoded as a string, and returns the
|
63
|
+
#corresponding InChI identifier.
|
64
|
+
def read(molfile)
|
65
|
+
write_input(molfile)
|
66
|
+
|
67
|
+
@main.run(create_argv)
|
68
|
+
|
69
|
+
get_inchi
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def write_input(molfile)
|
75
|
+
@in.open
|
76
|
+
@in << molfile
|
77
|
+
@in.close
|
78
|
+
end
|
79
|
+
|
80
|
+
def create_argv
|
81
|
+
result = ["", @in.path, @out.path, @log.path, @prob.path]
|
82
|
+
|
83
|
+
@options.each do |x|
|
84
|
+
result << x
|
85
|
+
end
|
86
|
+
|
87
|
+
result;
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_inchi
|
91
|
+
result = ""
|
92
|
+
|
93
|
+
@out.open
|
94
|
+
|
95
|
+
2.times do |i|
|
96
|
+
begin
|
97
|
+
@out.readline
|
98
|
+
|
99
|
+
rescue EOFError
|
100
|
+
raise "Unreadable molfile"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
result = @out.readline.rstrip!
|
105
|
+
|
106
|
+
@out.close
|
107
|
+
|
108
|
+
result
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|