Skip to content

About

GlyContact: a Python package for retrieving, processing, and analyzing 3D glycan structures.

Topics

Resources

Stars

15 stars

Watchers

2 watching

Forks

Repository files navigation

GlyContact

Glycan 3D structures, analyzed at scale.
Hand it a sequence. It brings the conformers and returns contacts, surface accessibility, flexibility, torsions, and hydrogen bonds.

PyPI Python versions Tests codecov Documentation Nature Communications paper

A core-fucosylated N-glycan in 3D with SNFG symbols, next to its monosaccharide contact map

Glycans are branched and flexible, so much of their function lives in a 3D landscape that a linear sequence only hints at. GlyContact connects the sequence you already have to atomic-resolution structures from GlycoShape molecular dynamics, NMR, or X-ray crystallography, and turns them into numbers, figures, and machine learning features.

  • Sequence in, structures out. Pass an IUPAC sequence and GlyContact fetches its conformers from the GlycoShape API and caches them. Your own PDB files work the same way, through my_path.
  • Ensembles, not snapshots. Contact frequencies, torsions, and hydrogen bonds are computed across conformer clusters and weighted by their populations.
  • Free, bound, and attached. Binding pockets, per-contact interaction classes, and glycan shielding cover lectin complexes and glycoproteins alike.
  • Ready for machine learning. 1,476 annotated structure graphs ship with the package, and the [ml] extra trains models that sample structure ensembles for any sequence.
  • Figures worth publishing. Every plot is drawn with viscose, and one word changes its palette.

Documentation: https://bojarlab.github.io/glycontact/ · Examples: lectin complexes and glycoproteins · Cite: Thomès et al., 2025

Install

pip install glycontact
pip install "glycontact[ml]"   # adds torch and torch-geometric for the machine learning layer

See it in 3D

plot_glycan_3D draws any conformer with 3D-SNFG symbols in an interactive py3Dmol view, inside your notebook. The structure at the top of this page comes from this call.

from glycontact.visualize import plot_glycan_3D
glycan = "Gal(b1-4)GlcNAc(b1-2)Man(a1-3)[Gal(b1-4)GlcNAc(b1-2)Man(a1-6)]Man(b1-4)GlcNAc(b1-4)[Fuc(a1-6)]GlcNAc"
plot_glycan_3D(glycan)

Contact maps

Contact maps show which monosaccharides sit close together in space, and so which parts of a glycan act as one surface. You get one table per conformer cluster, with the closest contacts drawn darkest.

from glycontact.process import get_contact_tables
from glycontact.visualize import draw_contact_map
contact_tables = get_contact_tables(glycan, level = "monosaccharide")
draw_contact_map(contact_tables[0], size = 1.0)

Monosaccharide contact map of a core-fucosylated N-glycan, with the closest contacts darkest

Surface accessibility and flexibility

Solvent-accessible surface area and flexibility decide what a binding partner can reach. plot_glycan_score paints them straight onto the SNFG drawing, with the most exposed residues glowing strongest.

from glycontact.visualize import plot_glycan_score
plot_glycan_score(glycan, attribute = "SASA")

SNFG drawing of the N-glycan with a glow around each residue that reflects its surface accessibility

Torsion angles

Glycosidic torsions set the overall shape of a glycan. ramachandran_plot pools them across every structure that carries a linkage.

from glycontact.visualize import ramachandran_plot
fig = ramachandran_plot("Gal(b1-4)GlcNAc")

Ramachandran plot of the Gal(b1-4)GlcNAc linkage, colored by density

get_linkage_conformations gives the same view for one glycan, weighted by conformer population and with gg/gt/tg rotamers for linkages to O6.

from glycontact.process import get_linkage_conformations
print(get_linkage_conformations(glycan).head().to_string(index = False))
      linkage  n_conformers  phi_mean  phi_sd  psi_mean  psi_sd  omega_mean  omega_sd  gg  gt  tg
 10_NAG-9_MAN             5    -80.07   12.60    167.23    5.29         NaN       NaN NaN NaN NaN
11_GAL-10_NAG             5    -64.52    5.33   -116.76    8.54         NaN       NaN NaN NaN NaN
  3_FUC-2_NAG             5    -76.55    2.46    177.25   13.46      -83.72     10.23 1.0 0.0 0.0
  4_NAG-2_NAG             5    -76.48    3.29   -121.53    9.13         NaN       NaN NaN NaN NaN
  5_BMA-4_NAG             5    -84.01   38.24   -123.50   15.52         NaN       NaN NaN NaN NaN

Hydrogen bonds

get_hydrogen_bonds finds the inter-residue hydrogen bonds that hold a conformation together, with their occupancy across the ensemble.

from glycontact.process import get_hydrogen_bonds
print(get_hydrogen_bonds(glycan).head().to_string(index = False))
 donor_residue        donor donor_atom  acceptor_residue     acceptor acceptor_atom  occupancy  distance  angle
            10 GlcNAc(b1-2)         O3                11    Gal(b1-4)            O5        0.8      3.00 141.68
             4 GlcNAc(b1-4)         N2                 3    Fuc(a1-6)            O2        0.6      3.01 156.65
             2 GlcNAc(b1-1)         O3                 4 GlcNAc(b1-4)            O5        0.6      2.80 141.05
             7 GlcNAc(b1-2)         O3                 8    Gal(b1-4)            O5        0.6      2.80 159.19
             3    Fuc(a1-6)         O2                 7 GlcNAc(b1-2)            O3        0.4      2.79 157.55

What a motif does to a structure

find_difference compares every pair of glycans that differ only by a motif and tests the change in any structural property.

from glycontact.process import structure_graphs
from glycontact.visualize import find_difference
result = find_difference(list(structure_graphs), pattern = "[Fuc(a1-6)]", metric = "SASA", plot = True)

Paired comparison of the SASA of glycans with and without core fucose

Glycans bound to proteins

glycontact.structure works on any PDB file. It reads the glycans out of it and classifies every contact with the protein into hydrogen bonds, CH-π stacking, metal coordination, covalent bonds, and van der Waals contacts.

from glycontact.structure import get_glycan_sequences_from_pdb, get_glycan_protein_interactions
print(get_glycan_sequences_from_pdb("3ZW1.pdb"))
interactions = get_glycan_protein_interactions("Fuc(a1-3)[Gal(b1-4)]GlcNAc(b1-3)Gal", "3ZW1.pdb")
print(interactions.head().to_string(index = False))
['Fuc(a1-3)[Gal(b1-4)]GlcNAc(b1-3)Gal', 'Fuc(a1-3)GlcNAc']
glycan_chain glycan_residue     IUPAC glycan_atom chain  resSeq resName protein_atom  distance   interaction
           D          4_GAL Gal(b1-4)          O6     A       8     TRP          NE1  3.254790 hydrogen_bond
           D          3_FUC Fuc(a1-3)          O5     A      15     ARG          NH2  2.825438 hydrogen_bond
           D          3_FUC Fuc(a1-3)          O4     A      15     ARG           NE  2.905937 hydrogen_bond
           D          3_FUC Fuc(a1-3)          O5     A      15     ARG           NE  3.352896 hydrogen_bond
           D          4_GAL Gal(b1-4)          C6     A      15     ARG          NH2  3.831360 van_der_Waals

One word, four palettes

Every plotting function takes palette, and viscose.set_palette sets one for a whole session.

fig = ramachandran_plot("Gal(b1-4)GlcNAc", palette = "lumen")

The same Ramachandran plot in the viscose palettes Lumen, Couture, Poster, and Aura

Everything in the box

Retrieve download_from_glycoshape, get_example_pdb, fetch_pdbs, convert_ID, get_all_clusters_frequency, extract_3D_coordinates
Contacts get_contact_tables, make_atom_contact_table, make_monosaccharide_contact_table, inter_structure_frequency_table, inter_structure_variability_table
Surface and flexibility get_sasa_table, compute_merge_SASA_flexibility, calculate_torsion_flexibility_per_residue
Geometry get_glycosidic_torsions, get_linkage_conformations, get_ring_conformations, get_hydrogen_bonds, analyze_torsion_torsion_correlations
Proteins get_binding_pocket, get_glycan_shielding, get_glycan_protein_interactions, get_glycan_sequences_from_pdb, annotation_pipeline
Comparison superimpose_glycans, get_similar_glycans, find_difference
Plots draw_contact_map, plot_glycan_3D, plot_glycan_score, plot_superimposed_glycans, plot_monosaccharide_instability, ramachandran_plot, show_correlations, show_correlation_dendrogram, make_gif
Machine learning get_all_structure_graphs, create_dataset, train_model, evaluate_model, predict_structure_ensemble, GINSweetNet, VonMisesSweetNet

The documentation covers each of them, and examples.ipynb and ConformerLearning.ipynb walk through lectin complexes, glycoproteins, and conformer prediction.

Citation

If you use GlyContact in your research, please cite Thomès et al., GlyContact analyzes glycan 3D structures at scale. Nat Commun 16:11136, 2025.

Contributing and license

Contributions are welcome, so please feel free to open a pull request. GlyContact is released under the MIT License, as detailed in the LICENSE file.

About

GlyContact: a Python package for retrieving, processing, and analyzing 3D glycan structures.

Topics

Resources

Stars

15 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages