Class: Chemicalml::Cml::ReferenceResolver
- Inherits:
-
Object
- Object
- Chemicalml::Cml::ReferenceResolver
- Defined in:
- lib/chemicalml/cml/reference_resolver.rb
Overview
Walks a CML document and resolves id-based references to the actual target wire instances. Useful for callers that need to follow CML references programmatically (e.g. bond → atoms, atomParity → atoms, map → molecules).
References are attribute values like atomRefs2="a1 a2",
atomRefs4="a1 a2 a3 a4", bondRefs="b1 b2", ref="m1".
The values are whitespace-separated lists of ids.
The resolver is opt-in: it does not modify the wire tree. Callers use it to perform lookups; unresolved refs are reported in a list (a constraint turns this list into warnings).
Instance Attribute Summary collapse
-
#document ⇒ Object
readonly
Returns the value of attribute document.
Instance Method Summary collapse
-
#atom_index ⇒ Object
Lazily-built => Atom index.
-
#bond_index ⇒ Object
Lazily-built => Bond index.
-
#find_atom(_molecule, atom_id) ⇒ Object
Returns the Atom with the given id within the given molecule, or nil if not found.
-
#find_bond(_molecule, bond_id) ⇒ Object
Returns the Bond with the given id within the given molecule, or nil if not found.
-
#initialize(document) ⇒ ReferenceResolver
constructor
A new instance of ReferenceResolver.
-
#resolve_atom_refs2(bond, molecule = containing_molecule(bond)) ⇒ Object
Resolves
bond.atom_refs2to a pair of [Atom, Atom]. -
#unresolved_refs ⇒ Object
Walks the whole document and reports every reference attribute whose target id is missing.
Constructor Details
#initialize(document) ⇒ ReferenceResolver
Returns a new instance of ReferenceResolver.
23 24 25 26 27 |
# File 'lib/chemicalml/cml/reference_resolver.rb', line 23 def initialize(document) @document = document @atom_index = nil @bond_index = nil end |
Instance Attribute Details
#document ⇒ Object (readonly)
Returns the value of attribute document.
18 19 20 |
# File 'lib/chemicalml/cml/reference_resolver.rb', line 18 def document @document end |
Instance Method Details
#atom_index ⇒ Object
Lazily-built => Atom index. Speeds up find_atom and
reference-resolution lookups from O(n) to O(1).
31 32 33 34 35 36 37 |
# File 'lib/chemicalml/cml/reference_resolver.rb', line 31 def atom_index @atom_index ||= begin hash = {} document.each_atom { |a| hash[a.id] = a if a.id } hash end end |
#bond_index ⇒ Object
Lazily-built => Bond index.
40 41 42 43 44 45 46 |
# File 'lib/chemicalml/cml/reference_resolver.rb', line 40 def bond_index @bond_index ||= begin hash = {} document.each_bond { |b| hash[b.id] = b if b.id } hash end end |
#find_atom(_molecule, atom_id) ⇒ Object
Returns the Atom with the given id within the given molecule, or nil if not found.
50 51 52 53 54 |
# File 'lib/chemicalml/cml/reference_resolver.rb', line 50 def find_atom(_molecule, atom_id) return nil unless atom_id atom_index[atom_id] end |
#find_bond(_molecule, bond_id) ⇒ Object
Returns the Bond with the given id within the given molecule, or nil if not found.
58 59 60 61 62 |
# File 'lib/chemicalml/cml/reference_resolver.rb', line 58 def find_bond(_molecule, bond_id) return nil unless bond_id bond_index[bond_id] end |
#resolve_atom_refs2(bond, molecule = containing_molecule(bond)) ⇒ Object
Resolves bond.atom_refs2 to a pair of [Atom, Atom]. Returns
nils for missing atoms so callers can detect partial misses.
66 67 68 69 70 71 72 |
# File 'lib/chemicalml/cml/reference_resolver.rb', line 66 def resolve_atom_refs2(bond, molecule = containing_molecule(bond)) ids = parse_refs(bond&.atom_refs2) return [] if ids.empty? return [nil, nil] if ids.size != 2 ids.map { |id| find_atom(molecule, id) } end |
#unresolved_refs ⇒ Object
Walks the whole document and reports every reference attribute whose target id is missing. Returns a list of hashes:
{ node: <Bond>, attr: :atom_refs2, missing: ["a99"] }
78 79 80 81 82 83 84 |
# File 'lib/chemicalml/cml/reference_resolver.rb', line 78 def unresolved_refs results = [] visit(@document) do |node| results.concat(unresolved_for(node)) end results end |