chemruby 0.9.3 → 1.1.9
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 +2 -2
- data/Rakefile +67 -63
- data/ext/extconf.rb +2 -0
- data/ext/subcomp.c +461 -320
- data/ext/utils.c +56 -0
- data/ext/utils.h +13 -0
- data/lib/chem.rb +34 -8
- data/lib/chem/db.rb +8 -0
- data/lib/chem/db/cansmi.rb +1 -1
- data/lib/chem/db/cdx.rb +1 -1
- data/lib/chem/db/cml.rb +52 -0
- data/lib/chem/db/gd.rb +64 -0
- data/lib/chem/db/gspan.rb +2 -2
- data/lib/chem/db/kcf_rpair.rb +34 -0
- data/lib/chem/db/kegg.rb +35 -1
- data/lib/chem/db/mdl.rb +75 -34
- data/lib/chem/db/opsin.rb +24 -0
- data/lib/chem/db/pdb.rb +105 -0
- data/lib/chem/db/pdf.rb +2 -0
- data/lib/chem/db/pubchem.rb +1071 -88
- data/lib/chem/db/rmagick.rb +5 -3
- data/lib/chem/db/sdf.rb +28 -2
- data/lib/chem/db/smiles/smiles.ry +27 -25
- data/lib/chem/db/smiles/smiparser.rb +29 -27
- data/lib/chem/db/types/type_gd.rb +35 -0
- data/lib/chem/db/types/type_gspan.rb +2 -2
- data/lib/chem/db/types/type_kcf.rb +19 -0
- data/lib/chem/db/types/type_kegg.rb +2 -0
- data/lib/chem/db/types/type_mdl.rb +1 -1
- data/lib/chem/db/types/type_png.rb +5 -1
- data/lib/chem/db/types/type_rdf.rb +22 -0
- data/lib/chem/db/types/type_xyz.rb +1 -1
- data/lib/chem/db/vector.rb +19 -3
- data/lib/chem/model.rb +5 -2
- data/lib/chem/utils.rb +17 -1
- data/lib/chem/utils/bitdb.rb +49 -0
- data/lib/chem/utils/cas.rb +28 -0
- data/lib/chem/utils/cdk.rb +403 -0
- data/lib/chem/utils/fingerprint.rb +98 -0
- data/lib/chem/utils/geometry.rb +8 -0
- data/lib/chem/utils/net.rb +303 -0
- data/lib/chem/utils/once.rb +28 -0
- data/lib/chem/utils/openbabel.rb +204 -0
- data/lib/chem/utils/sssr.rb +33 -25
- data/lib/chem/utils/sub.rb +6 -0
- data/lib/chem/utils/transform.rb +9 -8
- data/lib/chem/utils/ullmann.rb +138 -95
- data/lib/graph.rb +5 -6
- data/lib/graph/utils.rb +8 -0
- data/sample/calc_maximum_common_subgraph.rb +27 -0
- data/sample/calc_properties.rb +9 -0
- data/sample/data/atp.mol +69 -0
- data/sample/data/pioglitazone.mol +58 -0
- data/sample/data/rosiglitazone.mol +55 -0
- data/sample/data/troglitazone.mol +70 -0
- data/sample/find_compound_by_keggapi.rb +19 -0
- data/sample/generate_inchi.rb +7 -0
- data/sample/generate_substructurekey.rb +11 -0
- data/sample/images/ex6.rb +17 -0
- data/sample/images/ex7.rb +18 -0
- data/sample/iupac2mol.rb +8 -0
- data/sample/kekule.rb +13 -0
- data/sample/logp.rb +4 -0
- data/sample/mcs.rb +13 -0
- data/sample/mol2pdf.rb +8 -0
- data/sample/pubchem_fetch.rb +8 -0
- data/sample/pubchem_search.rb +12 -0
- data/sample/rosiglitazone.mol +57 -0
- data/sample/smarts.rb +10 -0
- data/sample/structure_match.rb +8 -0
- data/sample/structure_match_color.rb +22 -0
- data/sample/thiazolidinedione.mol +19 -0
- data/sample/troglitazone.mol +232 -0
- data/sample/vicinity.rb +8 -0
- data/test/data/CID_704.sdf +236 -0
- data/test/data/CID_994.sdf +146 -0
- data/test/data/db_EXPT03276.txt +321 -0
- data/test/data/pioglitazone.mol +58 -0
- data/test/data/rosiglitazone.mol +55 -0
- data/test/data/thiazolidinedione.mol +19 -0
- data/test/data/troglitazone.mol +70 -0
- data/test/{test_adj.rb → tc_adj.rb} +0 -0
- data/test/{test_canonical_smiles.rb → tc_canonical_smiles.rb} +0 -0
- data/test/tc_casrn.rb +17 -0
- data/test/tc_cdk.rb +89 -0
- data/test/{test_cdx.rb → tc_cdx.rb} +0 -0
- data/test/{test_chem.rb → tc_chem.rb} +0 -0
- data/test/{test_cluster.rb → tc_cluster.rb} +0 -0
- data/test/{test_db.rb → tc_db.rb} +0 -0
- data/test/tc_develop.rb +38 -0
- data/test/tc_drugbank.rb +13 -0
- data/test/{test_eps.rb → tc_eps.rb} +0 -0
- data/test/tc_gd.rb +8 -0
- data/test/{test_geometry.rb → tc_geometry.rb} +0 -0
- data/test/tc_graph.rb +15 -0
- data/test/{test_gspan.rb → tc_gspan.rb} +0 -0
- data/test/{test_iupac.rb → tc_iupac.rb} +0 -0
- data/test/{test_kcf.rb → tc_kcf.rb} +0 -0
- data/test/{test_kcf_glycan.rb → tc_kcf_glycan.rb} +0 -0
- data/test/{test_kegg.rb → tc_kegg.rb} +13 -0
- data/test/{test_linucs.rb → tc_linucs.rb} +0 -0
- data/test/{test_mdl.rb → tc_mdl.rb} +20 -0
- data/test/{test_mol2.rb → tc_mol2.rb} +1 -1
- data/test/{test_morgan.rb → tc_morgan.rb} +0 -0
- data/test/tc_net.rb +5 -0
- data/test/tc_once.rb +29 -0
- data/test/tc_openbabel.rb +57 -0
- data/test/{test_pdf.rb → tc_pdf.rb} +0 -0
- data/test/{test_prop.rb → tc_prop.rb} +1 -1
- data/test/tc_pubchem.rb +32 -0
- data/test/{test_rmagick.rb → tc_rmagick.rb} +0 -0
- data/test/{test_sbdb.rb → tc_sbdb.rb} +0 -0
- data/test/{test_sdf.rb → tc_sdf.rb} +2 -0
- data/test/{test_smiles.rb → tc_smiles.rb} +46 -30
- data/test/tc_sssr.rb +1 -0
- data/test/{test_sub.rb → tc_sub.rb} +0 -0
- data/test/tc_subcomp.rb +59 -0
- data/test/{test_traverse.rb → tc_traverse.rb} +0 -0
- data/test/{test_writer.rb → tc_writer.rb} +0 -0
- data/test/{test_xyz.rb → tc_xyz.rb} +0 -0
- data/test/ts_current.rb +11 -0
- data/test/ts_image.rb +6 -0
- data/test/ts_main.rb +12 -0
- metadata +259 -194
- data/lib/chem/utils/graph_db.rb +0 -146
- data/test/test_sssr.rb +0 -18
- data/test/test_subcomp.rb +0 -37
data/ext/utils.c
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include "utils.h"
|
3
|
+
|
4
|
+
int
|
5
|
+
ntz(long l){
|
6
|
+
int n;
|
7
|
+
if(l == 0) return ARCH;
|
8
|
+
n = 1;
|
9
|
+
if(( l & 0x000FFFF) == 0) { n = n + 16 ; l = l >> 16; }
|
10
|
+
if(( l & 0x00000FF) == 0) { n = n + 8 ; l = l >> 8; }
|
11
|
+
if(( l & 0x000000F) == 0) { n = n + 4 ; l = l >> 4; }
|
12
|
+
if(( l & 0x0000003) == 0) { n = n + 2 ; l = l >> 2; }
|
13
|
+
return n - (l & 1);
|
14
|
+
}
|
15
|
+
|
16
|
+
int
|
17
|
+
m_ntz(long *l, int n_bytes){
|
18
|
+
int i, n;
|
19
|
+
n = 0;
|
20
|
+
for(i = 0 ; i < n_bytes ; i++){
|
21
|
+
if(l[i] == 0){
|
22
|
+
n += ARCH;
|
23
|
+
}else{
|
24
|
+
return n + ntz(l[i]);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
return n;
|
28
|
+
}
|
29
|
+
|
30
|
+
void *
|
31
|
+
talloc(size_t size){
|
32
|
+
void * ptr;
|
33
|
+
ptr = malloc(size);
|
34
|
+
if(ptr == NULL){
|
35
|
+
rb_raise(rb_eNoMemError, "Cannot allocate memory");
|
36
|
+
}
|
37
|
+
return ptr;
|
38
|
+
}
|
39
|
+
|
40
|
+
void *
|
41
|
+
trealloc(void *from, size_t size){
|
42
|
+
void * ptr;
|
43
|
+
ptr = realloc(from, size);
|
44
|
+
if(ptr == NULL){
|
45
|
+
rb_raise(rb_eNoMemError, "Cannot allocate memory");
|
46
|
+
}
|
47
|
+
return ptr;
|
48
|
+
}
|
49
|
+
|
50
|
+
void
|
51
|
+
dump_long(long l, int n){
|
52
|
+
int i;
|
53
|
+
for(i = 0 ; i < n ; i++){
|
54
|
+
printf("%s", (l & (1 << i)) != 0 ? "@" : ".");
|
55
|
+
}
|
56
|
+
}
|
data/ext/utils.h
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
|
3
|
+
#define ARCH 32
|
4
|
+
|
5
|
+
#define NBYTES(width) ((width - 1 ) / ARCH + 1)
|
6
|
+
#define BITON(mat, h, w, n_bytes) (mat[h * n_bytes + w / ARCH] |= (1 << (w % ARCH)))
|
7
|
+
#define BITOFF(mat, h, w, n_bytes) (mat[h * n_bytes + w / ARCH] &= ~(1 << (w % ARCH)))
|
8
|
+
|
9
|
+
int ntz(long l);
|
10
|
+
int m_ntz(long *l, int n_bytes);
|
11
|
+
void * talloc(size_t size);
|
12
|
+
void * trealloc(void *from, size_t size);
|
13
|
+
void dump_long(long l, int n);
|
data/lib/chem.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Chem module. See documentation for the file chem.rb for an overview
|
3
3
|
#
|
4
|
-
# $Id: chem.rb
|
4
|
+
# $Id: chem.rb 160 2006-02-14 06:49:37Z tanaka $
|
5
5
|
#
|
6
6
|
# == Introduction
|
7
7
|
#
|
@@ -20,6 +20,7 @@
|
|
20
20
|
|
21
21
|
|
22
22
|
require 'stringio'
|
23
|
+
require 'graph'
|
23
24
|
|
24
25
|
require 'chem/data'
|
25
26
|
require 'chem/utils'
|
@@ -29,7 +30,17 @@ require 'chem/db'
|
|
29
30
|
|
30
31
|
require 'tempfile'
|
31
32
|
|
33
|
+
# Convension over Configuration
|
34
|
+
|
32
35
|
module Chem
|
36
|
+
# read ~/.chemrc or...
|
37
|
+
if ENV["HOME"]
|
38
|
+
DefaultDataDir = File.join(ENV["HOME"], "data")
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.data_dir
|
42
|
+
DefaultDataDir
|
43
|
+
end
|
33
44
|
|
34
45
|
autoload :MDL, 'chem/db/mdl.rb'
|
35
46
|
autoload :CDX, 'chem/db/cdx.rb'
|
@@ -38,11 +49,6 @@ module Chem
|
|
38
49
|
|
39
50
|
module_function
|
40
51
|
|
41
|
-
# returns first entry
|
42
|
-
def find_first str
|
43
|
-
p str
|
44
|
-
end
|
45
|
-
|
46
52
|
# format_class = Chem.autodetect("file.mol")
|
47
53
|
#
|
48
54
|
# Automatically detect file type and returns
|
@@ -70,12 +76,14 @@ module Chem
|
|
70
76
|
end
|
71
77
|
|
72
78
|
alias :parse_file :open_mol
|
79
|
+
alias :load :open_mol
|
73
80
|
module_function :parse_file
|
81
|
+
module_function :load
|
74
82
|
|
75
83
|
#
|
76
|
-
def self.save(array, filename)
|
84
|
+
def self.save(array, filename, params = {})
|
77
85
|
format = autodetect filename
|
78
|
-
format.save(array, filename)
|
86
|
+
format.save(array, filename, params)
|
79
87
|
end
|
80
88
|
|
81
89
|
def parse_smiles smiles
|
@@ -115,6 +123,24 @@ module Chem
|
|
115
123
|
format.save(self, filename, params)
|
116
124
|
end
|
117
125
|
|
126
|
+
# Redirect methods to OpenBabel
|
127
|
+
def method_missing(m, *args)
|
128
|
+
unless @ob_mol.respond_to?(m)
|
129
|
+
super(m, *args)
|
130
|
+
end
|
131
|
+
@ob_mol.__send__(m, *args)
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
module Atom
|
137
|
+
def method_missing(m, *args)
|
138
|
+
if not @ob_atom.nil? and @ob_atom.respond_to?(m)
|
139
|
+
@ob_atom.__send__(m, *args)
|
140
|
+
else
|
141
|
+
super(m, *args)
|
142
|
+
end
|
143
|
+
end
|
118
144
|
end
|
119
145
|
|
120
146
|
end
|
data/lib/chem/db.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
|
2
2
|
#require 'chem/db/smiles'
|
3
|
+
require 'chem/db/pubchem'
|
4
|
+
require 'chem/utils/openbabel'
|
5
|
+
require 'chem/utils/cdk'
|
6
|
+
require 'chem/db/opsin'
|
7
|
+
require 'chem/db/cml'
|
8
|
+
|
3
9
|
|
4
10
|
module Chem
|
5
11
|
|
@@ -30,6 +36,8 @@ module Chem
|
|
30
36
|
|
31
37
|
end
|
32
38
|
|
39
|
+
require 'chem/db/vector'
|
40
|
+
|
33
41
|
Chem::Db::load
|
34
42
|
|
35
43
|
__END__
|
data/lib/chem/db/cansmi.rb
CHANGED
data/lib/chem/db/cdx.rb
CHANGED
data/lib/chem/db/cml.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module Chem
|
4
|
+
|
5
|
+
class CMLAtom
|
6
|
+
|
7
|
+
include Atom
|
8
|
+
attr_reader :node_id
|
9
|
+
|
10
|
+
def initialize(element, node_id)
|
11
|
+
@element = element
|
12
|
+
@node_id = node_id
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
class CMLBond
|
18
|
+
|
19
|
+
include Bond
|
20
|
+
|
21
|
+
def initialize(v)
|
22
|
+
@v = v
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class CMLMolecule
|
28
|
+
include Molecule
|
29
|
+
|
30
|
+
def initialize(str)
|
31
|
+
@nodes = []
|
32
|
+
@edges = []
|
33
|
+
atom_refs = {}
|
34
|
+
|
35
|
+
xml = REXML::Document.new(str)
|
36
|
+
xml.elements.each("cml/molecule") do |molecule|
|
37
|
+
molecule.elements.each("atomArray/atom") do |atom_element|
|
38
|
+
atom = CMLAtom.new(atom_element.attributes["elementType"],
|
39
|
+
atom_element.attributes["id"])
|
40
|
+
@nodes << atom
|
41
|
+
atom_refs[atom.node_id] = atom
|
42
|
+
end
|
43
|
+
molecule.elements.each("bondArray/bond") do |bond_element|
|
44
|
+
from, to = (bond_element.attributes["atomRefs2"]).split(" ")
|
45
|
+
valence = bond_element.attributes["order"].to_i
|
46
|
+
@edges << [CMLBond.new(valence), atom_refs[from], atom_refs[to]]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
data/lib/chem/db/gd.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# RMagick adaptor for chem/db/vector.rb
|
2
|
+
|
3
|
+
require 'chem/db/vector'
|
4
|
+
|
5
|
+
module Chem
|
6
|
+
class GDWriter
|
7
|
+
|
8
|
+
include Writer
|
9
|
+
|
10
|
+
# Constructor for GD Adaptor
|
11
|
+
# See chem/db/vector.rb for detail parameters
|
12
|
+
def initialize mol, params
|
13
|
+
params[:size] ||= [350, 350]
|
14
|
+
params[:orig_point] ||= [10, 10]
|
15
|
+
params[:margin] ||= [10, 10]
|
16
|
+
@default_pointsize = (params[:pointsize] ? params[:pointsize] : 14)
|
17
|
+
params[:upside_down] = params[:upside_down] ? false : true
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
# Draws line
|
22
|
+
# This method may be invoked from chem/db/vector.rb
|
23
|
+
def line(from, to, color)
|
24
|
+
a_color = @img.colorAllocate(*to_256(color))
|
25
|
+
@img.line(from[0], from[1], to[0], to[1], a_color)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.save(mol, filename, params)
|
29
|
+
writer = self.new(mol, params)
|
30
|
+
writer.draw(filename, params)
|
31
|
+
end
|
32
|
+
|
33
|
+
def fill(nodes, color, params = {})
|
34
|
+
poly = GD::Polygon.new
|
35
|
+
nodes.each do |node|
|
36
|
+
poly.addPt(node[0], node[1])
|
37
|
+
end
|
38
|
+
@img.filledPolygon(poly, @img.colorAllocate(*to_256(color)))
|
39
|
+
end
|
40
|
+
|
41
|
+
def text(str, x, y, params = {})
|
42
|
+
font = GD::Font::LargeFont
|
43
|
+
a_color = nil
|
44
|
+
a_color = params[:color] ? @img.colorAllocate(*to_256(params[:color])) : @img.colorAllocate(0, 0, 0)
|
45
|
+
@img.string(font, x - font.width / 2.0, y - font.height / 2.0, str, a_color)
|
46
|
+
end
|
47
|
+
|
48
|
+
def draw filename, params
|
49
|
+
|
50
|
+
x, y = params[:size]
|
51
|
+
x += params[:margin][0] * 2
|
52
|
+
y += params[:margin][0] * 2
|
53
|
+
|
54
|
+
@img = GD::Image.new(x, y)
|
55
|
+
background_color = @img.colorAllocate(255, 255, 255)
|
56
|
+
|
57
|
+
# Vector#draw_body
|
58
|
+
draw_body
|
59
|
+
|
60
|
+
@img.png(open(filename, "w"))
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
data/lib/chem/db/gspan.rb
CHANGED
@@ -15,7 +15,7 @@ module Chem
|
|
15
15
|
class GSpan
|
16
16
|
|
17
17
|
FIRST_NODE = /\((\d+)\)/
|
18
|
-
REG_NODE
|
18
|
+
REG_NODE = /\s*(\d+)\s*\((\d*)(f|b)(\d+)\)/
|
19
19
|
|
20
20
|
# Parse one-lined gSpan formatted string and return
|
21
21
|
# molecule object.
|
@@ -45,7 +45,7 @@ module Chem
|
|
45
45
|
# Save molecule as gSpan formatted file.
|
46
46
|
# Example :
|
47
47
|
# Chem::GSpan.save(mols , "filename") # mols : an array of molecules
|
48
|
-
def self.save mols, filename
|
48
|
+
def self.save mols, filename, params = {}
|
49
49
|
open(filename, "w") do |out|
|
50
50
|
mols.each_with_index do |mol, mol_idx|
|
51
51
|
out.puts "t # #{mol_idx} -1 #{mol.name}"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# This is stub
|
2
|
+
module Chem
|
3
|
+
|
4
|
+
module KCF
|
5
|
+
|
6
|
+
class RPairMolecule
|
7
|
+
include Molecule
|
8
|
+
|
9
|
+
def initialize input
|
10
|
+
state = nil
|
11
|
+
input.each do |line|
|
12
|
+
case line[0..11]
|
13
|
+
when " "
|
14
|
+
case state
|
15
|
+
when :alignment
|
16
|
+
idx, from, to = line.split
|
17
|
+
from
|
18
|
+
end
|
19
|
+
when "ENTRY "
|
20
|
+
when "NAME "
|
21
|
+
when "COMPOUND "
|
22
|
+
when "TYPE "
|
23
|
+
when "ALIGN "
|
24
|
+
state = :alignment
|
25
|
+
p line[11..-1].strip.to_i
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/lib/chem/db/kegg.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# = chem/db/kegg.rb - KEGG (Kyoto Encylopedia of Genes and Genomes)
|
3
3
|
#
|
4
|
-
# Author:: Nobuya Tanaka <
|
4
|
+
# Author:: Nobuya Tanaka <t@chemruby.org>
|
5
5
|
#
|
6
6
|
# $Id:$
|
7
7
|
#
|
@@ -9,8 +9,42 @@
|
|
9
9
|
require 'chem/db/mdl'
|
10
10
|
|
11
11
|
module Chem
|
12
|
+
class KEGGException < Exception
|
13
|
+
end
|
12
14
|
|
13
15
|
module KEGG
|
16
|
+
|
17
|
+
CNUMREG = /C(\d\d\d\d\d)/
|
18
|
+
ECREG = /EC([^.]+)\.([^.]+)\.([^.]+)\.([^.]+)/
|
19
|
+
@@kegg = {}
|
20
|
+
|
21
|
+
def self.[](kegg_id)
|
22
|
+
@@kegg[kegg_id] ||= case kegg_id
|
23
|
+
when CNUMREG
|
24
|
+
when ECREG
|
25
|
+
EC.new($1, $2, $3, $4)
|
26
|
+
else
|
27
|
+
raise KEGGException, "Unknown KEGG ID '#{kegg_id}'"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Compound
|
32
|
+
end
|
33
|
+
|
34
|
+
class Reaction
|
35
|
+
end
|
36
|
+
|
37
|
+
module ReactionList
|
38
|
+
end
|
39
|
+
|
40
|
+
class EC
|
41
|
+
|
42
|
+
def initialize(num1, num2, num3, num4)
|
43
|
+
#puts Chem.data_dir
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
14
48
|
class KeggDirectory
|
15
49
|
|
16
50
|
attr_reader :dir
|
data/lib/chem/db/mdl.rb
CHANGED
@@ -2,18 +2,29 @@
|
|
2
2
|
# chem/db/mdl.rb - MDL molfile format class
|
3
3
|
#
|
4
4
|
|
5
|
+
require 'date'
|
5
6
|
|
6
7
|
module Chem
|
7
8
|
|
8
9
|
module Molecule
|
9
10
|
|
10
11
|
MDLCountLineFormat = "%3d%3d%3d%3d%3d%3d%3d%3d%3d 0999 V2000"
|
12
|
+
MDLHeaderLine2Format = "%2s%8s%02d%02d%02d%02d%02d"
|
11
13
|
|
12
|
-
def save_as_mdl
|
14
|
+
def save_as_mdl(filename)
|
13
15
|
File.open(filename, "w") do |out|
|
16
|
+
now = DateTime.now
|
17
|
+
out.puts
|
18
|
+
out.puts MDLHeaderLine2Format % [
|
19
|
+
" ",
|
20
|
+
"ChemRuby",
|
21
|
+
now.month,
|
22
|
+
now.mday,
|
23
|
+
now.year % 2000,
|
24
|
+
now.hour,
|
25
|
+
now.min
|
26
|
+
]
|
14
27
|
out.puts filename
|
15
|
-
out.puts # ChemRuby
|
16
|
-
out.puts
|
17
28
|
out.puts MDLCountLineFormat % [nodes.length, edges.length, 0, 0, 0, 0, 0, 0, 0]
|
18
29
|
nodes.each do |node|
|
19
30
|
out.puts node.to_mdl
|
@@ -21,6 +32,7 @@ module Chem
|
|
21
32
|
edges.each do |edge, atom1, atom2|
|
22
33
|
out.puts edge.to_mdl(nodes.index(atom1) + 1, nodes.index(atom2) + 1)
|
23
34
|
end
|
35
|
+
out.puts "M END"
|
24
36
|
end
|
25
37
|
end
|
26
38
|
|
@@ -30,7 +42,10 @@ module Chem
|
|
30
42
|
|
31
43
|
MDLAtomLineFormat = "%10.4f%10.4f%10.4f %2s%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d%3d"
|
32
44
|
|
33
|
-
def to_mdl
|
45
|
+
def to_mdl(mapping = 0)
|
46
|
+
self.x ||= 0
|
47
|
+
self.y ||= 0
|
48
|
+
self.z ||= 0
|
34
49
|
MDLAtomLineFormat % [x, y, z, element, 0, 0, 0, 0, 0, 0, 0, 0, 0, mapping, 0, 0]
|
35
50
|
end
|
36
51
|
|
@@ -38,7 +53,7 @@ module Chem
|
|
38
53
|
|
39
54
|
module Bond
|
40
55
|
|
41
|
-
def to_mdl
|
56
|
+
def to_mdl(from, to)
|
42
57
|
"%3d%3d%3d%3d " % [from, to, v, 0]
|
43
58
|
end
|
44
59
|
|
@@ -46,20 +61,20 @@ module Chem
|
|
46
61
|
|
47
62
|
module Reaction
|
48
63
|
|
49
|
-
|
50
|
-
|
51
|
-
# out = STDOUT
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
64
|
+
# def to_mdl_rxn
|
65
|
+
# return # fix me
|
66
|
+
# # out = STDOUT
|
67
|
+
# out.puts "$RXN"
|
68
|
+
# out.puts
|
69
|
+
# out.puts "ISIS 112620051015"
|
70
|
+
# out.puts
|
71
|
+
# out.puts "%3d%3d" % [@reactants.length, @products.length]
|
72
|
+
# @reactants.each{ |mol| output_mdl_mol(mol, out)}
|
73
|
+
# @products.each{ |mol| output_mdl_mol(mol, out)}
|
74
|
+
# end
|
60
75
|
|
61
76
|
private
|
62
|
-
def output_mdl_mol
|
77
|
+
def output_mdl_mol(mol, out)
|
63
78
|
out.puts "$MOL"
|
64
79
|
mol.nodes.each do |node|
|
65
80
|
out.puts node.to_mdl(10)
|
@@ -73,9 +88,7 @@ module Chem
|
|
73
88
|
|
74
89
|
class MDLAtom
|
75
90
|
|
76
|
-
require 'chem/utils/transform'
|
77
91
|
include Atom
|
78
|
-
include Chem::Transform::ThreeDimension
|
79
92
|
|
80
93
|
Stereo = {
|
81
94
|
0 => :not_stereo,
|
@@ -149,7 +162,7 @@ module Chem
|
|
149
162
|
2 => :chain
|
150
163
|
}
|
151
164
|
|
152
|
-
def initialize
|
165
|
+
def initialize(line) ; @line = line ; end
|
153
166
|
|
154
167
|
def v ; @v ||= @line[6..8].to_i ; end
|
155
168
|
|
@@ -174,10 +187,29 @@ module Chem
|
|
174
187
|
end
|
175
188
|
alias name entry
|
176
189
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
190
|
+
attr_reader :mol_name
|
191
|
+
|
192
|
+
def program_name ; @program_name ||= @header_line2[2..9] end
|
193
|
+
|
194
|
+
def date_time
|
195
|
+
year_last_two = @header_line2[14..15].to_i
|
196
|
+
year = year_last_two + (year_last_two > 80 ? 1900 : 2000)
|
197
|
+
@date ||= DateTime.new(
|
198
|
+
year,
|
199
|
+
@header_line2[10..11].to_i,
|
200
|
+
@header_line2[12..13].to_i,
|
201
|
+
@header_line2[16..17].to_i,
|
202
|
+
@header_line2[18..19].to_i)
|
203
|
+
end
|
204
|
+
|
205
|
+
def dimensional_codes
|
206
|
+
@dimensional_codes ||= @header_line2[20..21]
|
207
|
+
end
|
208
|
+
|
209
|
+
def parse(input)
|
210
|
+
@mol_name = input.readline.chop
|
211
|
+
@header_line2 = input.readline.chop
|
212
|
+
raise MDLException if @comment = input.readline == nil
|
181
213
|
line = input.readline
|
182
214
|
n_atom = line[0..2].to_i
|
183
215
|
n_bond = line[3..5].to_i
|
@@ -224,12 +256,12 @@ module Chem
|
|
224
256
|
@edges = []
|
225
257
|
end
|
226
258
|
|
227
|
-
def self.parse_io
|
259
|
+
def self.parse_io(input)
|
228
260
|
mol = MdlMolecule.new
|
229
261
|
mol.parse input
|
230
262
|
end
|
231
263
|
|
232
|
-
def self.parse
|
264
|
+
def self.parse(file)
|
233
265
|
mol = MdlMolecule.new
|
234
266
|
input = open(file)
|
235
267
|
mol.parse input
|
@@ -239,18 +271,22 @@ module Chem
|
|
239
271
|
|
240
272
|
class RxnAtom
|
241
273
|
include Atom
|
242
|
-
attr_accessor :reactant, :product
|
274
|
+
# attr_accessor :reactant, :product
|
243
275
|
|
244
|
-
def reactant=
|
276
|
+
def reactant=(rct)
|
245
277
|
@reactant = @representative = rct
|
246
278
|
end
|
247
279
|
|
248
|
-
def method_missing
|
249
|
-
@representative.
|
280
|
+
def method_missing(name, *args)
|
281
|
+
if @representative.respond_to?(name)
|
282
|
+
@representative.send(name, *args)
|
283
|
+
else
|
284
|
+
super(name, *args)
|
285
|
+
end
|
250
286
|
end
|
251
287
|
|
252
288
|
|
253
|
-
def product=
|
289
|
+
def product=(prd)
|
254
290
|
@product = prd
|
255
291
|
@representative = prd unless @representative
|
256
292
|
end
|
@@ -341,7 +377,7 @@ module Chem
|
|
341
377
|
end
|
342
378
|
|
343
379
|
private
|
344
|
-
def get_edge_hash
|
380
|
+
def get_edge_hash(mols, hash)
|
345
381
|
mols.each do |mol|
|
346
382
|
mol.edges.each do |edge, atom1, atom2|
|
347
383
|
hash[[atom1, atom2].sort_by{|a| a.number}] = edge
|
@@ -350,7 +386,7 @@ module Chem
|
|
350
386
|
end
|
351
387
|
|
352
388
|
private
|
353
|
-
def read_mol
|
389
|
+
def read_mol(input, n, mols, atoms)
|
354
390
|
n.times do
|
355
391
|
loop do
|
356
392
|
line = input.readline # $MOL
|
@@ -366,13 +402,18 @@ module Chem
|
|
366
402
|
end
|
367
403
|
|
368
404
|
private
|
369
|
-
def parse_header
|
405
|
+
def parse_header(input)
|
370
406
|
4.times{|n| input.readline}
|
371
407
|
input.readline.split.collect{|n| n.to_i}
|
372
408
|
end
|
373
409
|
|
374
410
|
end
|
375
411
|
|
412
|
+
module RDFParser
|
413
|
+
def initialize(input)
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
376
417
|
end
|
377
418
|
|
378
419
|
end
|