Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions inspect/interaction_counts/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<html>
<head>
<title>Mol* Gallery</title>
<meta charset="UTF-8" />
</head>

<body style="font-family: sans-serif; height: 100%; width: 100%; margin: 0;">
<div id="app" style="height: 100%;width: 100%;">
<canvas id="canvas" style="height: 100%;width: 100%;"></canvas>
</div>

<script src="src/index.ts"></script>
</body>
</html>
24 changes: 24 additions & 0 deletions inspect/interaction_counts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "molstar-typescript-example",
"version": "1.0.0",
"description": "Molstar and TypeScript example starter project",
"main": "index.html",
"scripts": {
"start": "parcel index.html",
"build": "parcel build index.html"
},
"dependencies": {
"parcel-bundler": "1.12.5",
"molstar": "4.3.0"
},
"devDependencies": {
"typescript": "4.4.4"
},
"resolutions": {
"@babel/preset-env": "7.13.8"
},
"keywords": [
"typescript",
"molstar"
]
}
19 changes: 19 additions & 0 deletions inspect/interaction_counts/src/common/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { PluginContext } from "molstar/lib/mol-plugin/context";
import { DefaultPluginSpec } from "molstar/lib/mol-plugin/spec";

export async function createRootViewer() {
const viewport = document.getElementById("app") as HTMLDivElement;
const canvas = document.getElementById("canvas") as HTMLCanvasElement;

const plugin = new PluginContext(DefaultPluginSpec());
await plugin.init();

if (!plugin.initViewer(canvas, viewport)) {
viewport.innerHTML = "Failed to init Mol*";
throw new Error("init failed");
}
//@ts-ignore
window["molstar"] = plugin;

return plugin;
}
80 changes: 80 additions & 0 deletions inspect/interaction_counts/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { createRootViewer } from "./common/init";
import { Queries, QueryContext, StructureProperties, StructureSelection } from "molstar/lib/mol-model/structure";
import { InteractionsProvider } from "molstar/lib/mol-model-props/computed/interactions";
import { SyncRuntimeContext } from "molstar/lib/mol-task/execution/synchronous";
import { interactionTypeLabel } from "molstar/lib/mol-model-props/computed/interactions/common";

async function init() {
// Create viewer
const plugin = await createRootViewer();

// Download PDB
const fileData = await plugin.builders.data.download(
{ url: "https://models.rcsb.org/4hhb.bcif", isBinary: true }
);

// Load PDB and create representation
const trajectory = await plugin.builders.structure.parseTrajectory(fileData, "mmcif");
const presetStateObjects = await plugin.builders.structure.hierarchy.applyPreset(trajectory, "default");

if (!presetStateObjects) {
throw new Error("Structure not loaded");
}

// Get Structure object from the structure stateObject selector.
// The Structure object contains properties and accessors to the underlying molecular data such as chains, residues, atoms, etc.
const struct = presetStateObjects.structure.data!;

// Create a QueryContext to limit the query to the structure
const queryCtx = new QueryContext(struct);
// Create a query that selects all residues that are HETATM and in chain A
const ligQuery = Queries.generators.residues({
chainTest: ctx => StructureProperties.chain.auth_asym_id(ctx.element) === 'A',
atomTest: ctx => StructureProperties.residue.group_PDB(ctx.element) === 'HETATM'
});
// Since this example has at least 1 ligand with multiple atoms, we can assume a Sequence
const ligSelection = ligQuery(queryCtx) as StructureSelection.Sequence;
// Create a set of unit ids to filter out interactions that don't involve our selection
const filterIds = new Set<number>([]);
ligSelection.structures.forEach(s => {
s.units.forEach(u => {
filterIds.add(u.id);
})
})

// For interactions, create an InteractionsProvider that will calculate
// the interactions on the attached structure
const customPropCtx = {
runtime: SyncRuntimeContext, // Use global synchronous runtime
assetManager: plugin.managers.asset // use existing asset manager
};
await InteractionsProvider.attach(customPropCtx, struct);

// Find the interactions for the structure
const interactions = InteractionsProvider.get(struct).value!;
const { contacts } = interactions;

// Keep a count of the number of interaction types
const interactionCounts = [0, 0, 0, 0, 0, 0, 0, 0, 0]; // Array of 9 elements, one for each InteractionType
// Iterate over all contacts in the structure
for (let i=0; i<contacts.edgeCount; i++) {
const c = contacts.edges[i];
// Remap the UnitId from the inter-unit graph to the structure Unit
const unitA = struct.unitMap.get(c.unitA);
const unitB = struct.unitMap.get(c.unitB);
// Skip interactions that don't involve the ligand.
// There are 2N edges (one for A-B and one for B-A) so we can
// skip any edges that don't have our selection in unitA
if (!filterIds.has(unitA.id)) continue;
// Skip self-interactions
if (unitA.id === unitB.id) continue;
// Increment the count for the interaction type
interactionCounts[c.props.type]++;
}
console.table(interactionCounts.map((count, type) => [interactionTypeLabel(type), count]))

// Highlight the StructureSelection for easier visualization
const loci = StructureSelection.toLociWithSourceUnits(ligSelection) // create loci of selection
plugin.managers.structure.selection.fromLoci('add', loci) // highlight selection
}
init();
16 changes: 16 additions & 0 deletions inspect/interaction_counts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"strict": true,
"module": "commonjs",
"jsx": "preserve",
"esModuleInterop": true,
"sourceMap": true,
"allowJs": true,
"lib": [
"es6",
"dom"
],
"rootDir": "src",
"moduleResolution": "node"
}
}
2 changes: 2 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ npm run watch
- [Set transparency on selection](https://codesandbox.io/p/sandbox/github/molstar/example-gallery/master/representation/transparency_using_selection)
- Coloring
- [Color a selection](https://codesandbox.io/p/sandbox/github/molstar/example-gallery/master/coloring/color_a_selection)
- Inspect
- [Interaction counts](https://codesandbox.io/p/sandbox/github/molstar/example-gallery/master/inspect/interaction_counts)
- [Default](https://codesandbox.io/p/sandbox/github/molstar/example-gallery/master/default)

## Prebuilt Examples and CodePens
Expand Down