Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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/list_entities/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/list_entities/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/list_entities/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;
}
113 changes: 113 additions & 0 deletions inspect/list_entities/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { Queries, QueryContext, StructureProperties, StructureSelection } from "molstar/lib/mol-model/structure";
import { createRootViewer } from "./common/init";
import { StructureSelectionQueries, StructureSelectionQuery } from "molstar/lib/mol-plugin-state/helpers/structure-selection-query";
import { MolScriptBuilder as MS } from 'molstar/lib/mol-script/language/builder';
import { Location } from "molstar/lib/mol-model/structure/structure/element/location";


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

// Download PDB
const fileData = await plugin.builders.data.download(
{ url: "https://models.rcsb.org/1PTH.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 be reused for all queries
// Limits the queries to only look at the structure
const ctx = new QueryContext(struct)


// ==== Number of Waters ====
// Created a query to select all residues that are water
// but only select 1 atom per water (ensuring a Singleton selection)
const waterQuery = Queries.generators.atoms({
'entityTest': ctx => StructureProperties.entity.type(ctx.element) === 'water',
'atomTest': ctx => StructureProperties.atom.type_symbol(ctx.element) === 'O'
})
// Can cast as a Singleton selection since we are only selecting 1 atom per water
const waterSelection = waterQuery(ctx) as StructureSelection.Singletons;
const numWaters = waterSelection.structure.atomicResidueCount;


// ==== Covalent ligand names and residue code ====
// Create a query expression for all ligands connected to the protein
const covalentLigandExp = MS.struct.filter.isConnectedTo({
0: StructureSelectionQueries.ligand.expression, // All ligands
target: StructureSelectionQueries.protein.expression, // All protein atoms
'bond-test': true // Only atoms covalently bound to the protein
})
// Query the atoms with the context to get a StructureSelection
const covLigQuery = StructureSelectionQuery('only-covalent-ligands', covalentLigandExp).query;
const covLigSelection = covLigQuery(ctx);
// Assume ligands in structure have >1 atoms.
// Therefore, the StructureSelection must be a Sequence
const covLigStructures = (covLigSelection as StructureSelection.Sequence).structures;
// Retrieve each ligand name and residue code
const covLigNames: string[] = [];
const covLigRes: string[] = [];
covLigStructures.forEach(s => s.units.map(u => {
// Create a location for the first element of the ligand
// to retrieve structure properties
const location = Location.create(s, u, u.elements[0])
// Return the ligand name property for the ligand
const name = StructureProperties.entity.pdbx_description(location).join('|')
covLigNames.push(name);
// Return the residue code for the ligand
const res = StructureProperties.atom.label_comp_id(location)
covLigRes.push(res);
}))


// ==== Number of AltLoc positions ====
const altLocQuery = Queries.generators.atoms({
// Any atom with a non '' alt_id
'atomTest': ctx => !!StructureProperties.atom.label_alt_id(ctx.element),
});
// Can only select 1 atom at a time, must be a Singleton
const altLocSelection = altLocQuery(ctx) as StructureSelection.Singletons;
const numAltLocs = altLocSelection.structure.elementCount;


// ==== Polymer ASYM Unit name and chain ====
const polymerSelection = StructureSelectionQueries.polymer.query(ctx)
// Assume more than 1 atom in the polymer entity
const polymerStructues = (polymerSelection as StructureSelection.Sequence).structures;
// Iterate over each polymer unit in each structure and get the name and chain
const namePolymers: string[] = [];
const chainPolymers: string[] = [];
polymerStructues.forEach(s => {
s.units.map(u => {
// Create a location for the polymer unit to retrieve structure properties
const location = Location.create(struct, u, u.elements[0])
// Retrieve the polymer name and chain
const name = StructureProperties.entity.pdbx_description(location).join('|')
namePolymers.push(name);
const chain = StructureProperties.chain.auth_asym_id(location);
chainPolymers.push(chain);
})
})

console.table([
{title: 'Water count', value: numWaters},
{title: 'Covalent Ligand name', value: covLigNames.join(', ')},
{title: 'Covalent Ligand residue', value: covLigRes.join(', ')},
{title: 'Alt Loc Count', value: numAltLocs},
{title: 'Poly ASYM Unit name', value: namePolymers.join(', ')},
{title: 'Poly ASYM Unit chain', value: chainPolymers.join(', ')}
])
}
init();
16 changes: 16 additions & 0 deletions inspect/list_entities/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 @@ -50,6 +50,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
- [List entities](https://codesandbox.io/p/sandbox/github/molstar/example-gallery/master/inspect/list_entities)
- [Default](https://codesandbox.io/p/sandbox/github/molstar/example-gallery/master/default)

## Prebuilt Examples and CodePens
Expand Down