Skip to content

Read and inspect molecules

The Molecule class is the main entry point for working with oligonucleotides. You can create a Molecule using the from_X methods or the generic read() method.

Every example on this page uses a library you have already loaded. HELMshaker ships no monomers, so reading without one raises MonomerLibraryError. See Monomer Libraries for how to get one.

from helmshaker import MonomerLibrary

library = MonomerLibrary()
library.load_from_file("monomers.json")  # your dictionary, or one pulled from TMR

Reading from HELM

from helmshaker import Molecule

helm = 'CHEM1{[Ahx]}|CHEM2{[PEG220]}|CHEM3{[PEG4]}|CHEM4{[PEG4]}|RNA1{p}|RNA2{p}|RNA3{p}|RNA4{p.[d](C)p.[d](A)p.[lna](G)}$CHEM2,RNA4,1:R2-1:R1|CHEM3,RNA1,1:R1-1:R2|CHEM3,RNA2,1:R2-1:R1|CHEM4,RNA2,1:R1-1:R2|CHEM4,RNA3,1:R2-1:R1$$$V2.0'

# Using the from_helm convenience method
molecule = Molecule.from_helm(helm, monomer_library=library)

# Or using the generic read method
molecule = Molecule.read(helm, notation="helm", monomer_library=library)

Reading from XNA

The dots represent the nucleotide separation in a HELM.

xna = {
    'polymers': {
        'CHEM1': {'CHEM': 'Ahx'},
        'CHEM2': {'CHEM': 'PEG220'},
        'CHEM3': {'CHEM': 'PEG4'},
        'CHEM4': {'CHEM': 'PEG4'},
        'RNA1': {'phosphate': 'p'},
        'RNA2': {'phosphate': 'p'},
        'RNA3': {'phosphate': 'p'},
        'RNA4': {'base': '.C.A.G', 'phosphate': 'p.p.p.', 'sugar': '.d.d.lna'}
    },
    'connections': ['CHEM2,RNA4,1:R2-1:R1', 'CHEM3,RNA1,1:R1-1:R2', 'CHEM3,RNA2,1:R2-1:R1', 'CHEM4,RNA2,1:R1-1:R2', 'CHEM4,RNA3,1:R2-1:R1']
}

molecule = Molecule.from_xna(xna, monomer_library=library)

# Convert to HELM
print(molecule.to_helm())

Reading from Sequence

# Single strand
molecule = Molecule.from_sequence("ACGUACGU", monomer_library=library)

# Multiple strands
molecule = Molecule.from_sequence(["ACGUACGU", "UGCAUGCA"], monomer_library=library)

print(molecule.to_helm())

Reading from Other Notations

Use from_notation() (or the generic read() method) to read token-based vendor/CRO notations. HELMshaker ships with a bundled example mapping:

# Bundled 'example' notation - single strand
tokens = "AeCeGeUeAdCdGdTd"
molecule = Molecule.from_notation(tokens, notation="example", monomer_library=library)

# Bundled 'example' notation - two strands
tokens = ["AeCeGeUe", "AdCdGdTd"]
molecule = Molecule.from_notation(tokens, notation="example", monomer_library=library)

Read any other notation by passing your own token-to-HELM mapping file via mapping_path:

molecule = Molecule.from_notation(
    "AeCeGeUe",
    notation="myvendor",
    mapping_path="myvendor.json",
    monomer_library=library,
)

Accessing Molecule Data

Once the molecule is created, you can access its internal data structure:

molecule = Molecule.from_helm(helm, monomer_library=library)

# Access the internal data (returns a deep copy)
data = molecule.data

data.polymers      # Dict of polymer IDs to Polymer objects
data.connections   # List of Connection objects

Polymer Structure

The polymers attribute is a dictionary where the key is the polymer ID (e.g., "RNA1", "CHEM1"). The value is a Polymer object with:

  • polymer.type: The type of polymer, e.g. "RNA", "CHEM"
  • polymer.index: The numeric index, "1", "2", etc.
  • polymer.id: The full ID (computed as type + index), e.g. "RNA1"
  • polymer.residues: List of Residue objects

Each Residue contains a list of Monomer objects:

  • monomer.id: The monomer symbol, e.g. "m", "A", "m5C"
  • monomer.type: The type of monomer: "sugar", "base", "phosphate", or "CHEM"
  • monomer.uuid: The unique identifier from the monomer library

For example:

polymer = molecule.data.polymers["RNA4"]
# Polymer(type='RNA', index='4', residues=[...])

residue = polymer.residues[0]
# Residue(type='nucleotide', monomers=[Monomer(...), Monomer(...), ...])

Validation Results

After modifying a molecule, you can validate it:

molecule = Molecule.from_helm("RNA1{r(A)p.r(G)}$$$$V2.0", monomer_library=library)
molecule.validate()

result = molecule.get_validation_result()
print(result.is_valid)
print(result.warnings)
print(result.errors)

Method Chaining

HELMshaker supports a fluent interface for chaining operations:

helm = "RNA1{[moe](A)[sp].[moe](U)[sp].[moe](G)}$$$$V2.0"

result = (
    Molecule.from_helm(helm, monomer_library=library)
    .apply_pattern("moe_gapmer_5_10_5")
    .validate()
    .to_helm()
)