Skip to content

Conversation

@douweschulte
Copy link
Member

@douweschulte douweschulte commented Feb 18, 2025

I have been thinking about rendering glycan structures for a while and my thoughts were recently reinvigorated in a discussion with @mobiusklein. This is how far I have gotten by now. Please let me know if there are any things I am missing.

Here is a preview, on the top with my rendering engine, on the bottom the same glycans by glytoucan
image
Note the glytoucan rendering of G04421VO differes in the fact that my renderer always renders rooted trees while the glytoucan also allows unrooted trees

Things I want to add:

  • Fragments rendering (to annotate spectra as we did in the Annotator paper)
    • Breaking symbol + ensure correct angle for line
  • Rendering the original Amino acid
    • Allow ~ as symbol for the full peptide
  • Looking into a way of keeping the isomeric state of Nonose to be able to colour Kdo green instead of Red (as done in the preview)
  • Think about the best way to render modification text, now it can clash with branches
    • Build the possibility of modifications footnotes
  • Be able to render in multiple orientations (top down, left right etc)
  • Be able to render to a bitmap instead of spitting out an svg string (easy enough by using zeno)
  • Potentially it could be nice to add more info in the svg, like full glycan name. positions etc, to allow for interactive uses
  • Fix up split diamonds/triangles/squares to also have rectangular corners in the split corner
  • Be able to change the main foreground and background colour

Things that I do not think I can solve right now:

  • Currently the location of glycan substituents is not tracked, so showing that is not possible
  • The linkage of monosaccharides is also not tracked, so that is also not possible to show
  • Cyclic, linear, repeating patterns, and other complex glycan cases that are extremely improbable on peptides (at least as far as I know)

Ping: @ShelleyJager

@douweschulte
Copy link
Member Author

Current state of the render test:
all_glycans

@mobiusklein
Copy link
Contributor

Linear glycans are not uncommon. Glycosaminoglycans are almost all linear and are heavily modified. They are found on proteoglycans, proteins that are found on cell surfaces and secreted into extracellular spaces.

image

With SVG generation, a recurring pattern is to compute your geoms on unit scale, and then use group elements with a transform attribute to scale them and move them to where you want to put them. This is also useful for arranging groups of elements because of how transforms propagate down the DOM tree. Whether you want to try that or not is up to you since you've already done the geometry calculations here.

The layout of substituents is tricky without position or linkage, but what I found useful when I did this in glypy was to keep track of occupied sides/angles around each monosaccharide glyph and pick an unoccupied location to indicate substituents.

Doing all of this without an explicit coordinate system with bounding boxes is probably going to make your life harder in the long run.

@douweschulte
Copy link
Member Author

douweschulte commented Feb 20, 2025

Current state of the render test:
Screen Shot 2025-02-20 at 18 09 41
(Branch breakages still need a symbol, I am basing this on the figures for the Annotator paper)

@douweschulte
Copy link
Member Author

@mobiusklein I for now am mostly interested in using these in the Annotator, so in displaying the glycans on peptides and fragments of glycans in spectra. I assumed I would not need linear glycans for these. Rendering these could still be done, but to be honest my experience with them is even less than peptide attached glycans. The svg transform is very nice indeed, but I was thinking about allowing direct rendering to bitmap, so I wanted to not use any of more advanced positioning capabilities of svg. If this turns out to be infeasible I will happily revert to using them and just allowing svg output. A fallback of glycan modification text sounds good, I have hard bounding boxes for all graphics except for the text as I want to use proportional fonts. I could go in and use the dependency I was thinking about for bitmap rendering in the svg rendering as well to be able to calculate the text width though so that might be the way to go. Either way I think I will have to build in a footnoting system at some point to allow obscenely big modification lists to still work, and this might make it possible to footnote the modifications if there is no good spot available.

@douweschulte
Copy link
Member Author

Current state of the render test:
Screen Shot 2025-02-21 at 16 14 38

@douweschulte
Copy link
Member Author

Current state of the render test:
Screen Shot 2025-02-25 at 12 55 11

@douweschulte
Copy link
Member Author

Current state of the render test:
Screen Shot 2025-02-26 at 12 29 07

@douweschulte
Copy link
Member Author

Current state of the render test:
Screen Shot 2025-02-26 at 16 16 55

@douweschulte
Copy link
Member Author

Current state of the render test: (Left SVG right bitmap)
Screen Shot 2025-03-03 at 16 45 14

@douweschulte
Copy link
Member Author

@mobiusklein do you want to review some more or can I just merge?

Current state of the render test:
Screen Shot 2025-03-04 at 13 43 31

@mobiusklein
Copy link
Contributor

The renderings look good. I haven't had a chance to do a re-read of the code yet as there's a lot of it.

From a brief scan, are you attempting to canonicalize glycans to prefer a specific ordering of branches?

@douweschulte douweschulte marked this pull request as ready for review March 12, 2025 13:17
@douweschulte
Copy link
Member Author

douweschulte commented Mar 12, 2025

The branches are kept in the same order as they appear in the original definition. That way they are rendered in the same order as the images in GlyTouCan/GNOme. For naming the branches I do reorder them though, so alpha/beta/gamma/etc indicates the order when the branches are sorted on mass, as is customary as far as I know. So Y4α is the 4th bond from the end of the heaviest branch.

@mobiusklein
Copy link
Contributor

Thank you. The databases store glycans in their canonicalized ordering, and last I checked (five years ago now), they canonicalize input structures sent to their APIs.

Branch labeling isn't controlled by a particular algorithm. Some of implementations order branches based upon their canonical ordering according to GlycoCT's sorting algorithm, others might use something based upon the Domon & Costello notation, which is similar but less intricate. My approach in glypy was just "take the order things are in and traverse as-is, trusting that the caller has things sorted the way they want", and separately implement the GlycoCT canonicalization algorithm. I'm not advocating doing this that way (or any way) unless you decide you need it.

I'll need to take some time later to read the rest of the changes

Copy link
Contributor

@mobiusklein mobiusklein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't review everything, especially the geometry, without a more lengthy testing period. I had some questions about how the fragment specification data structure works though.

The general ideas seem to work and they render well. I cannot tell how "scaling" will work yet, and whether font size is independent of overall size.

Co-authored-by: Joshua Klein <mobiusklein@gmail.com>
@douweschulte
Copy link
Member Author

Thanks so much for the review, it really helped with getting the nitty gritty details of the structures right. On font size, this is always half the sugar size.

@douweschulte douweschulte merged commit 1067c01 into main Mar 24, 2025
8 checks passed
@douweschulte douweschulte deleted the glycan-rendering branch June 23, 2025 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants