molstar icon indicating copy to clipboard operation
molstar copied to clipboard

Question: How to visualize docking outputs in embedded HTML?

Open smbatyankh opened this issue 10 months ago • 6 comments

Hello everyone,

I'm reaching out to see if anyone knows how to visualize both protein and ligand interactions. Currently, I've managed to implement two methods for visualizing them in embedded HTML, but I'm still unable to show their interactions clearly. Is there a method to merge structures seamlessly and visualize them within embedded HTML? I'd appreciate any insights or suggestions.

Below is the code I'm currently using for the visualization:

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <link rel="icon" href="./favicon.ico" type="image/x-icon">
        <title>Embedded Mol* Viewer</title>
        <style>
            #app {
                display: flex;
                flex-direction: column
                align-items: stretch;
                height: 100vh;
                margin: 0;
                padding: 0;
            }
        </style>
        <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/molstar@latest/build/viewer/molstar.css" />
    </head>
    <body>
        <div id="app"></div>
        <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/molstar@latest/build/viewer/molstar.js"></script>
        <script type="text/javascript">
            molstar.Viewer.create('app', {
                layoutIsExpanded: false,
                layoutShowControls: false,
                layoutShowRemoteState: false,
                layoutShowSequence: true,
                layoutShowLog: false,
                layoutShowLeftPanel: false,

                viewportShowExpand: false,
                viewportShowSelectionMode: true,
                viewportShowAnimation: true,

                pdbProvider: 'rcsb',
                emdbProvider: 'rcsb',
            }).then(viewer => {
            ...
async function loadStructureAndLigand(viewer, mainData, mainFormat, ligands, dataLabel = 'protein') {
    await loadStructureExplicitly(viewer, mainData, mainFormat, dataLabel);

    async function visualizeLigand(data, format, label) {
        const _data = await viewer.plugin.builders.data.rawData({ data: data, label: label });
        const trajectory = await viewer.plugin.builders.structure.parseTrajectory(_data, format);
        const model = await viewer.plugin.builders.structure.createModel(trajectory);
        const structure = await viewer.plugin.builders.structure.createStructure(model);

        const ligandComponent = await viewer.plugin.builders.structure.tryCreateComponentStatic(structure, 'ligand');
        if (ligandComponent) {
            const builder = viewer.plugin.builders.structure.representation;
            const update = viewer.plugin.build();
            builder.buildRepresentation(update, ligandComponent, {
                type: 'ball-and-stick',
                typeParams: { alpha: 1 },
                colorTheme: { name: 'element-symbol' }
            }, { tag: label });
            await update.commit();
        }
    }

    for (let ligand of ligands) {
        await visualizeLigand(ligand.data, ligand.format, ligand.label || 'ligand');
    }
}


async function loadStructureExplicitly(viewer, data, format, dataLabel = 'protein') {
    const _data = await viewer.plugin.builders.data.rawData({ data: data, label: dataLabel });
    const trajectory = await viewer.plugin.builders.structure.parseTrajectory(_data, format);
    const model = await viewer.plugin.builders.structure.createModel(trajectory);
    const structure = await viewer.plugin.builders.structure.createStructure(model);

    const components = {
        polymer: await viewer.plugin.builders.structure.tryCreateComponentStatic(structure, 'polymer'),
        ligand: await viewer.plugin.builders.structure.tryCreateComponentStatic(structure, 'ligand'),
        water: await viewer.plugin.builders.structure.tryCreateComponentStatic(structure, 'water'),
    };

    const builder = viewer.plugin.builders.structure.representation;
    const update = viewer.plugin.build();
    if (components.polymer) {
        builder.buildRepresentation(update, components.polymer, {
            type: 'cartoon',
            typeParams: {
                alpha: 1,
                quality: 'high'
            }
        }, { tag: 'polymer-cartoon' });

        builder.buildRepresentation(update, components.polymer, {
            type: 'gaussian-surface',
            typeParams: {
                alpha: 0,
                quality: 'high',
                smoothness: 1
            },
            colorTheme: { name: 'hydrophobicity' }
        }, { tag: 'polymer-surface' });
    }
    if (components.ligand) builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick' }, { tag: 'ligand' });
    if (components.water) builder.buildRepresentation(update, components.water, { type: 'ball-and-stick', typeParams: { alpha: 0.6 } }, { tag: 'water' });
    await update.commit();
}

...
var structureFormat = 'pdb'.trim();
var pocketFormat = 'xyz'.trim();
var ligandFormat = 'mol2'.trim();

...

        </script>
    </body>
</html>

smbatyankh avatar Apr 23 '24 11:04 smbatyankh

Have you seen the docking viewer example app?

dsehnal avatar Apr 23 '24 11:04 dsehnal

Yes, I attempted to use DockingViewer, but got 'undefined', which seems to indicate that the code is not accessible via the URL: https://cdn.jsdelivr.net/npm/molstar@latest/build/viewer/molstar.js

smbatyankh avatar Apr 23 '24 11:04 smbatyankh

I came across this response and am curious whether the implementation is still being planned or if it has already been completed: https://github.com/molstar/molstar/issues/185#issuecomment-841206018

smbatyankh avatar Apr 23 '24 11:04 smbatyankh

I am sorry, what you are after currently isn't possible via a JavaScript snippet in an HTML document. You will need to use a bundler (e.g. Vite).

dsehnal avatar Apr 23 '24 11:04 dsehnal

Thank you for your answer. I'll consider moving forward in that direction. Additionally, I have a quick question: can I enable basic animations, such as a spinning effect, using just this JavaScript snippet?

smbatyankh avatar Apr 24 '24 12:04 smbatyankh

This should work:

plugin.canvas3d.setProps({
  trackball: { animate: { name: 'spin', params: { speed: 1 } } } // or { name: 'off', params: { }}
});

dsehnal avatar Apr 25 '24 13:04 dsehnal