chem_scanner 0.1.3
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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +604 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +20 -0
- data/LICENSE.txt +661 -0
- data/README.md +177 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/chem_scanner.gemspec +43 -0
- data/lib/chem_scanner.rb +79 -0
- data/lib/chem_scanner/cdx.rb +67 -0
- data/lib/chem_scanner/cdxml.rb +72 -0
- data/lib/chem_scanner/chem_draw/cdx_reader.rb +101 -0
- data/lib/chem_scanner/chem_draw/node/base_node.rb +123 -0
- data/lib/chem_scanner/chem_draw/node/base_value.rb +257 -0
- data/lib/chem_scanner/chem_draw/node/bond.rb +100 -0
- data/lib/chem_scanner/chem_draw/node/bracket_attachment.rb +17 -0
- data/lib/chem_scanner/chem_draw/node/bracket_group.rb +32 -0
- data/lib/chem_scanner/chem_draw/node/chem_geometry.rb +58 -0
- data/lib/chem_scanner/chem_draw/node/color_table.rb +46 -0
- data/lib/chem_scanner/chem_draw/node/font_table.rb +54 -0
- data/lib/chem_scanner/chem_draw/node/fragment.rb +149 -0
- data/lib/chem_scanner/chem_draw/node/fragment_node.rb +145 -0
- data/lib/chem_scanner/chem_draw/node/graphic.rb +94 -0
- data/lib/chem_scanner/chem_draw/node/text.rb +242 -0
- data/lib/chem_scanner/chem_draw/parser.rb +214 -0
- data/lib/chem_scanner/chem_draw/yaml/cdx_objects.yaml +32 -0
- data/lib/chem_scanner/chem_draw/yaml/cdx_props.yaml +263 -0
- data/lib/chem_scanner/chem_draw/yaml/cdxml_objects.yaml +36 -0
- data/lib/chem_scanner/chem_draw/yaml/cdxml_props.yaml +263 -0
- data/lib/chem_scanner/chem_draw/yaml/props_data_type.yaml +263 -0
- data/lib/chem_scanner/configuration/abbreviation.rb +76 -0
- data/lib/chem_scanner/configuration/superatom.rb +76 -0
- data/lib/chem_scanner/configuration/superatom.txt +2874 -0
- data/lib/chem_scanner/configuration/util.rb +40 -0
- data/lib/chem_scanner/configuration/yaml/abbreviations.yaml +6399 -0
- data/lib/chem_scanner/configuration/yaml/elements.yaml +115 -0
- data/lib/chem_scanner/configuration/yaml/solvents.yaml +16 -0
- data/lib/chem_scanner/doc.rb +56 -0
- data/lib/chem_scanner/docx.rb +86 -0
- data/lib/chem_scanner/export/cml.rb +176 -0
- data/lib/chem_scanner/extension/element_map.rb +9 -0
- data/lib/chem_scanner/extension/geometry/bounding_box.rb +84 -0
- data/lib/chem_scanner/extension/geometry/line.rb +123 -0
- data/lib/chem_scanner/extension/geometry/point.rb +18 -0
- data/lib/chem_scanner/extension/geometry/polygon.rb +115 -0
- data/lib/chem_scanner/extension/geometry/segment.rb +196 -0
- data/lib/chem_scanner/extension/passthrough.rb +7 -0
- data/lib/chem_scanner/interpreter/element/arrow.rb +298 -0
- data/lib/chem_scanner/interpreter/element/atom.rb +134 -0
- data/lib/chem_scanner/interpreter/element/fragment.rb +59 -0
- data/lib/chem_scanner/interpreter/element/molecule.rb +473 -0
- data/lib/chem_scanner/interpreter/element/molecule_group.rb +34 -0
- data/lib/chem_scanner/interpreter/element/reaction.rb +186 -0
- data/lib/chem_scanner/interpreter/element/reaction_step.rb +39 -0
- data/lib/chem_scanner/interpreter/formula_to_mol.rb +75 -0
- data/lib/chem_scanner/interpreter/post_process/assemble.rb +38 -0
- data/lib/chem_scanner/interpreter/post_process/label_by_molecule.rb +37 -0
- data/lib/chem_scanner/interpreter/post_process/reaction_info.rb +225 -0
- data/lib/chem_scanner/interpreter/post_process/reaction_step.rb +95 -0
- data/lib/chem_scanner/interpreter/post_process/reagent_label.rb +46 -0
- data/lib/chem_scanner/interpreter/post_process/text_as_molecule.rb +52 -0
- data/lib/chem_scanner/interpreter/post_process/text_label.rb +40 -0
- data/lib/chem_scanner/interpreter/pre_process/arrow.rb +197 -0
- data/lib/chem_scanner/interpreter/pre_process/graphic.rb +41 -0
- data/lib/chem_scanner/interpreter/pre_process/molecule.rb +150 -0
- data/lib/chem_scanner/interpreter/reaction_detection/assign_to_reaction.rb +129 -0
- data/lib/chem_scanner/interpreter/reaction_detection/duplicate_reagents.rb +50 -0
- data/lib/chem_scanner/interpreter/reaction_detection/molecule_group.rb +55 -0
- data/lib/chem_scanner/interpreter/reaction_detection/multi_line_chain_reaction.rb +85 -0
- data/lib/chem_scanner/interpreter/reaction_detection/remove_separated_mol.rb +115 -0
- data/lib/chem_scanner/interpreter/reaction_detection/text_assignment.rb +166 -0
- data/lib/chem_scanner/interpreter/scheme.rb +173 -0
- data/lib/chem_scanner/interpreter/scheme_base.rb +64 -0
- data/lib/chem_scanner/interpreter/text_group/bold_groups.rb +183 -0
- data/lib/chem_scanner/interpreter/text_group/molecule_text_group.rb +138 -0
- data/lib/chem_scanner/interpreter/text_group/reaction_text_groups.rb +221 -0
- data/lib/chem_scanner/interpreter/text_group/retrieve_alias_info.rb +41 -0
- data/lib/chem_scanner/interpreter/text_group/retrieve_n_atoms.rb +106 -0
- data/lib/chem_scanner/interpreter/text_group/text_group_interpreter.rb +92 -0
- data/lib/chem_scanner/perkin_eln.rb +287 -0
- data/lib/chem_scanner/version.rb +5 -0
- data/lib/rubygems_plugin.rb +5 -0
- metadata +244 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChemScanner
|
|
4
|
+
module ChemDraw
|
|
5
|
+
CDX_BOND_ORDER = {
|
|
6
|
+
0x0001 => 1,
|
|
7
|
+
0x0002 => 2,
|
|
8
|
+
0x0004 => 3,
|
|
9
|
+
0x0008 => 4,
|
|
10
|
+
0x0010 => 5,
|
|
11
|
+
0x0020 => 6,
|
|
12
|
+
0x0040 => 0.5,
|
|
13
|
+
0x0080 => 1.5,
|
|
14
|
+
0x0100 => 2.5,
|
|
15
|
+
0x0200 => 3.5,
|
|
16
|
+
0x0400 => 4.5,
|
|
17
|
+
0x0800 => 5.5,
|
|
18
|
+
0x1000 => "dative",
|
|
19
|
+
0x2000 => "ionic",
|
|
20
|
+
0x4000 => "hydrogen",
|
|
21
|
+
}.freeze
|
|
22
|
+
|
|
23
|
+
CDXML_BOND_DISPLAY = {
|
|
24
|
+
"Solid" => 0,
|
|
25
|
+
"Dash" => 1,
|
|
26
|
+
"Hash" => 2,
|
|
27
|
+
"WedgedHashBegin" => 3,
|
|
28
|
+
"WedgedHashEnd" => 4,
|
|
29
|
+
"Bold" => 5,
|
|
30
|
+
"WedgeBegin" => 6,
|
|
31
|
+
"WedgeEnd" => 7,
|
|
32
|
+
"Wavy" => 8,
|
|
33
|
+
"HollowWedgeBegin" => 9,
|
|
34
|
+
"HollowWedgeEnd" => 10,
|
|
35
|
+
"WavyWedgeBegin" => 11,
|
|
36
|
+
"WavyWedgeEnd" => 12,
|
|
37
|
+
"Dot" => 13,
|
|
38
|
+
"DashDot" => 14,
|
|
39
|
+
}.freeze
|
|
40
|
+
|
|
41
|
+
# CDX Bond parser
|
|
42
|
+
class Bond < BaseNode
|
|
43
|
+
attr_accessor :begin_id, :end_id, :stereo, :order, :color
|
|
44
|
+
|
|
45
|
+
def initialize(parser, parser_type, id)
|
|
46
|
+
super(parser, parser_type, id)
|
|
47
|
+
|
|
48
|
+
@begin_id = nil
|
|
49
|
+
@end_id = nil
|
|
50
|
+
@stereo = 0
|
|
51
|
+
@order = 1
|
|
52
|
+
|
|
53
|
+
@color = 0
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def parse_node(tag, _id, data)
|
|
57
|
+
case @props_ref[tag]
|
|
58
|
+
when "Bond_Begin" then @begin_id = read_value(tag, data)
|
|
59
|
+
when "Bond_End" then @end_id = read_value(tag, data)
|
|
60
|
+
when "Bond_Order" then @order = bond_order(read_value(tag, data))
|
|
61
|
+
when "Bond_Display" then @stereo = bond_display(tag, data)
|
|
62
|
+
when "ForegroundColor" then @color = read_value(tag, data)
|
|
63
|
+
else do_unhandled(tag)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def bond_order(val)
|
|
68
|
+
return val if @parser_type == "cdxml"
|
|
69
|
+
|
|
70
|
+
CDX_BOND_ORDER[val] || 0
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def bond_display(tag, data)
|
|
74
|
+
return read_value(tag, data) if @parser_type == "cdx"
|
|
75
|
+
|
|
76
|
+
CDXML_BOND_DISPLAY[data.text]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def end_points
|
|
80
|
+
[@begin_id, @end_id]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def replace_endpoint(endpoint, new_point)
|
|
84
|
+
if @begin_id == endpoint
|
|
85
|
+
@begin_id = new_point
|
|
86
|
+
elsif @end_id == endpoint
|
|
87
|
+
@end_id = new_point
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def other_endpoint(endpoint)
|
|
92
|
+
endpoint == @begin_id ? @end_id : @begin_id
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def has_endpoint?(id)
|
|
96
|
+
[@begin_id, @end_id].include?(id)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChemScanner
|
|
4
|
+
module ChemDraw
|
|
5
|
+
# CDX Bracket parser
|
|
6
|
+
class BracketAttachment < BaseNode
|
|
7
|
+
attr_reader :graphic_id
|
|
8
|
+
|
|
9
|
+
def parse_node(tag, _id, data)
|
|
10
|
+
ref = @props_ref[tag] || @obj_ref[tag]
|
|
11
|
+
return unless ref == "Bracket_GraphicID"
|
|
12
|
+
|
|
13
|
+
@graphic_id = read_value(tag, data)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChemScanner
|
|
4
|
+
module ChemDraw
|
|
5
|
+
# CDX Bracket parser
|
|
6
|
+
class BracketGroup < BaseNode
|
|
7
|
+
require "chem_scanner/chem_draw/node/bracket_attachment"
|
|
8
|
+
|
|
9
|
+
attr_reader :attachments, :object_ids
|
|
10
|
+
|
|
11
|
+
def initialize(parser, parser_type, id)
|
|
12
|
+
super(parser, parser_type, id)
|
|
13
|
+
|
|
14
|
+
@attachments = []
|
|
15
|
+
@object_ids = []
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def parse_node(tag, id, data)
|
|
19
|
+
if @props_ref[tag] == "BracketedObjects"
|
|
20
|
+
@object_ids = read_value(tag, data)
|
|
21
|
+
return
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
return do_unhandled(tag) unless @obj_ref[tag] == "BracketAttachment"
|
|
25
|
+
|
|
26
|
+
attachment = BracketAttachment.new(@parser, @parser_type, id)
|
|
27
|
+
attachment.read
|
|
28
|
+
@attachments.push(attachment)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChemScanner
|
|
4
|
+
module ChemDraw
|
|
5
|
+
# Geometry parser
|
|
6
|
+
class ChemGeometry < BaseNode
|
|
7
|
+
attr_reader :tail, :head, :head_type, :nogo, :line_type
|
|
8
|
+
|
|
9
|
+
def initialize(parser, parser_type, id)
|
|
10
|
+
super(parser, parser_type, id)
|
|
11
|
+
|
|
12
|
+
@middle_points = []
|
|
13
|
+
@line_type = 0
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# NOTE: head ----> tail (head at tail)
|
|
17
|
+
def parse_node(tag, _nid, data)
|
|
18
|
+
case @props_ref[tag]
|
|
19
|
+
when "3DTail"
|
|
20
|
+
x, y = read_value(tag, data)
|
|
21
|
+
@tail = { x: x, y: y }
|
|
22
|
+
when "3DHead"
|
|
23
|
+
x, y = read_value(tag, data)
|
|
24
|
+
@head = { x: x, y: y }
|
|
25
|
+
when "Arrow_ArrowHead_Head"
|
|
26
|
+
@arrow_head = read_type(tag, data, CDXML_ARROW_TYPE)
|
|
27
|
+
when "Arrow_NoGo" then @nogo = read_value(tag, data)
|
|
28
|
+
when "Line_Type"
|
|
29
|
+
@line_type = read_type(tag, data, CDXML_LINE_TYPE)
|
|
30
|
+
else do_unhandled(tag)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def segment
|
|
35
|
+
Geometry::Segment.new_by_arrays(
|
|
36
|
+
[@tail[:x], @tail[:y]],
|
|
37
|
+
[@head[:x], @head[:y]],
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def vector
|
|
42
|
+
segment.to_vector
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def line
|
|
46
|
+
segment.to_line
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def headless
|
|
50
|
+
@arrow_head != 2
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def cross?
|
|
54
|
+
!@nogo.nil?
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module ChemScanner
|
|
2
|
+
module ChemDraw
|
|
3
|
+
# ColorTable
|
|
4
|
+
class ColorTable < BaseNode
|
|
5
|
+
attr_reader :table
|
|
6
|
+
|
|
7
|
+
def initialize(parser_type, data)
|
|
8
|
+
@parser_type = parser_type
|
|
9
|
+
@data = data
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def read
|
|
13
|
+
@parser_type == "cdx" ? read_cdx : read_cdxml
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def read_cdx
|
|
17
|
+
@nums = read_int(@data[0, 2], true)
|
|
18
|
+
rgbs = binary_chunks(@data[2..-1], 2).map { |x| read_int(x, true) }
|
|
19
|
+
|
|
20
|
+
table = rgbs.each_slice(3).to_a.map do |x|
|
|
21
|
+
x.reduce("") do |memo, c|
|
|
22
|
+
rgb = c >> 8
|
|
23
|
+
memo << rgb.to_s(16).rjust(2, "0")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@table = %w[000000 FFFFFF] + table
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def read_cdxml
|
|
31
|
+
table = @data.element_children.each_with_object([]) do |color, t|
|
|
32
|
+
next if color.name != "color"
|
|
33
|
+
|
|
34
|
+
rgb = %w[r g b].reduce("") do |memo, c|
|
|
35
|
+
ct = color.attr(c).to_i * 255
|
|
36
|
+
memo << ct.to_s(16).rjust(2, "0")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
t.push(rgb)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
@table = %w[000000 FFFFFF] + table
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChemScanner
|
|
4
|
+
module ChemDraw
|
|
5
|
+
# CDX Graphic parser
|
|
6
|
+
class FontTable < BaseNode
|
|
7
|
+
attr_reader :table
|
|
8
|
+
|
|
9
|
+
def initialize(parser_type, data)
|
|
10
|
+
@parser_type = parser_type
|
|
11
|
+
@data = data
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def read
|
|
15
|
+
@parser_type == "cdx" ? read_cdx : read_cdxml
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def read_cdx
|
|
19
|
+
@table = []
|
|
20
|
+
run_count = read_int(@data[2, 2], true)
|
|
21
|
+
|
|
22
|
+
iter = 4
|
|
23
|
+
(1..run_count).each do
|
|
24
|
+
font, length = read_cdx_font_attribute(iter)
|
|
25
|
+
@table.push(font)
|
|
26
|
+
iter += 6 + length
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
@table
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def read_cdx_font_attribute(iter)
|
|
33
|
+
id = read_int(@data[iter, 2], true)
|
|
34
|
+
charset = read_int(@data[iter + 2, 2], true)
|
|
35
|
+
length = read_int(@data[iter + 4, 2], true)
|
|
36
|
+
name = @data[iter + 6, length]
|
|
37
|
+
|
|
38
|
+
[{ id: id, charset: charset, name: name }, length]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def read_cdxml
|
|
42
|
+
@table = @data.element_children.each_with_object([]) do |font, table|
|
|
43
|
+
next if font.name != "font"
|
|
44
|
+
|
|
45
|
+
id = font.attr("id").to_i
|
|
46
|
+
charset = font.attr("charset")
|
|
47
|
+
name = font.attr("name")
|
|
48
|
+
|
|
49
|
+
table.push(id: id, charset: charset, name: name)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ChemScanner
|
|
4
|
+
module ChemDraw
|
|
5
|
+
# CDX Fragment parser
|
|
6
|
+
class Fragment < BaseNode
|
|
7
|
+
require "chem_scanner/chem_draw/node/fragment_node"
|
|
8
|
+
require "chem_scanner/chem_draw/node/bond"
|
|
9
|
+
|
|
10
|
+
attr_accessor :boxed, # indicate if fragment is boxed within an rectangle
|
|
11
|
+
:polygon, :node_map, :bond_map, :graphic_map
|
|
12
|
+
|
|
13
|
+
def initialize(parser, parser_type, id)
|
|
14
|
+
super(parser, parser_type, id)
|
|
15
|
+
@boxed = false
|
|
16
|
+
|
|
17
|
+
@node_map = {}
|
|
18
|
+
@bond_map = {}
|
|
19
|
+
|
|
20
|
+
@graphic_map = {}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def parse_node(tag, nid, _data)
|
|
24
|
+
case @props_ref.key?(tag) || @obj_ref[tag]
|
|
25
|
+
when "Node" then create_node(nid)
|
|
26
|
+
when "Bond" then create_bond(nid)
|
|
27
|
+
when "Graphic"
|
|
28
|
+
graphic = Graphic.new(@parser, @parser_type, id)
|
|
29
|
+
graphic.read
|
|
30
|
+
@graphic_map[id] = graphic
|
|
31
|
+
# when "BoundingBox" then @polygon = read_value(tag, data)
|
|
32
|
+
|
|
33
|
+
# NOTE: Indicates that this object represents some properties
|
|
34
|
+
# in some other objects.
|
|
35
|
+
# when "RepresentsProperty" then @represent = true
|
|
36
|
+
else do_unhandled(tag)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def post_parse_node
|
|
41
|
+
return if !@polygon.nil? || @node_map.count.zero?
|
|
42
|
+
|
|
43
|
+
rebuild_polygon
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def rebuild_polygon
|
|
47
|
+
fn = @node_map.first[1]
|
|
48
|
+
lb = Geometry::Point.new(fn.x, fn.y)
|
|
49
|
+
rt = Geometry::Point.new(fn.x, fn.y)
|
|
50
|
+
|
|
51
|
+
@node_map.each_value do |node|
|
|
52
|
+
# next if node.x.nil? || node.y.nil?
|
|
53
|
+
next if node.has_nil_coord?
|
|
54
|
+
|
|
55
|
+
nlb = node.leftbottom
|
|
56
|
+
nrt = node.righttop
|
|
57
|
+
|
|
58
|
+
lb.x = nlb.x if nlb.x < lb.x
|
|
59
|
+
lb.y = nlb.y if nlb.y < lb.y
|
|
60
|
+
|
|
61
|
+
rt.x = nrt.x if nrt.x > rt.x
|
|
62
|
+
rt.y = nrt.y if nrt.y > rt.y
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
points = [
|
|
66
|
+
Geometry::Point.new(lb.x, lb.y),
|
|
67
|
+
Geometry::Point.new(lb.x, rt.y),
|
|
68
|
+
Geometry::Point.new(rt.x, rt.y),
|
|
69
|
+
Geometry::Point.new(rt.x, lb.y),
|
|
70
|
+
]
|
|
71
|
+
@polygon = Geometry::Polygon.new(points)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def create_node(id)
|
|
75
|
+
node = FragmentNode.new(@parser, @parser_type, id)
|
|
76
|
+
node.read
|
|
77
|
+
@node_map[id] = node
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def create_bond(id)
|
|
81
|
+
bond = Bond.new(@parser, @parser_type, id)
|
|
82
|
+
bond.read
|
|
83
|
+
@bond_map[id] = bond
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def get_node_with_type(type)
|
|
87
|
+
@node_map.select { |_, v| v.type == type }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Check if fragment has ExternalConnectionPoint node
|
|
91
|
+
def get_external_point
|
|
92
|
+
get_node_with_type(12)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Get the internal id for Fragment node
|
|
96
|
+
def get_internal_nids
|
|
97
|
+
ext_node = get_external_point
|
|
98
|
+
return [] if ext_node.count.zero?
|
|
99
|
+
|
|
100
|
+
ext_ids = ext_node.keys
|
|
101
|
+
internal_ids = []
|
|
102
|
+
ext_ids.each do |ext_id|
|
|
103
|
+
hbond = bond_has_endpoint(ext_id)
|
|
104
|
+
_, bond = hbond
|
|
105
|
+
|
|
106
|
+
internal_ids.push(bond.other_endpoint(ext_id))
|
|
107
|
+
end
|
|
108
|
+
[ext_ids, internal_ids]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def bond_has_endpoint(endpoint)
|
|
112
|
+
@bond_map.detect { |_, b| b.end_points.include?(endpoint) }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def clone
|
|
116
|
+
cloned = self.class.new(@parser, @parser_type, @id)
|
|
117
|
+
cloned.boxed = @boxed
|
|
118
|
+
cloned.clone_node_map(@node_map)
|
|
119
|
+
cloned.clone_bond_map(@bond_map)
|
|
120
|
+
|
|
121
|
+
cloned
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def clone_node_map(node_map)
|
|
125
|
+
@node_map = {}
|
|
126
|
+
node_map.each do |k, v|
|
|
127
|
+
@node_map[k] = v
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def clone_bond_map(bond_map)
|
|
132
|
+
@bond_map = {}
|
|
133
|
+
bond_map.each do |k, v|
|
|
134
|
+
@bond_map[k] = v
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def set_new_id
|
|
139
|
+
new_id = @parser.get_tempid
|
|
140
|
+
set_id(new_id)
|
|
141
|
+
new_id
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def set_id(new_id)
|
|
145
|
+
@id = new_id
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|