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/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;
}
120 changes: 120 additions & 0 deletions inspect/list_entities/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
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'
})
// Since we used Queries.generators.atoms, our selection will by grouped by Atom and is therefore Singletons
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
// If the selection is empty, set the ligand structures to an empty array
const covLigStructures = StructureSelection.isEmpty(covLigSelection) ? [] : (covLigSelection as StructureSelection.Sequence).structures;
// Retrieve each ligand name and residue code
const covLigNames: string[] = [];
const covLigRes: string[] = [];
const auxCovLigLocation = Location.create(); // Create a Location object to retrieve properties
covLigStructures.forEach(s => {
auxCovLigLocation.structure = s; // Set the structure for the location
s.units.map(u => {
// Set the Location to the first element of the ligand
auxCovLigLocation.unit = u;
auxCovLigLocation.element = u.elements[0];
// Use the Location to query the ligand name property of the ligand
const name = StructureProperties.entity.pdbx_description(auxCovLigLocation).join('|')
covLigNames.push(name);
s// Use the Location to query the reidue code for the ligand
const res = StructureProperties.atom.label_comp_id(auxCovLigLocation)
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),
});
// Since we used Queries.generators.atoms, our selection will by grouped by Atom and is therefore Singletons
const altLocSelection = altLocQuery(ctx) as StructureSelection.Singletons;
const numAltLocs = altLocSelection.structure.elementCount;


// ==== Polymer ASYM Unit name and chain ====
const polymerSelection = StructureSelectionQueries.polymer.query(ctx)
// Polymer query groups selected atoms by entity. Assume it creates a Sequence StructureSelection
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[] = [];
const auxPolymerLocation = Location.create(); // Create a Location object to retrieve properties
polymerStructues.forEach(s => {
auxPolymerLocation.structure = s; // Set the structure for the location
s.units.map(u => {
// Set the Location to the first element of the polymer
auxPolymerLocation.unit = u;
auxPolymerLocation.element = u.elements[0];
// Use the Location to query the polymer name and chain
const name = StructureProperties.entity.pdbx_description(auxPolymerLocation).join('|')
namePolymers.push(name);
const chain = StructureProperties.chain.auth_asym_id(auxPolymerLocation);
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 @@ -55,6 +55,8 @@ npm run watch
- [Move camera](https://codesandbox.io/p/sandbox/github/molstar/example-gallery/master/camera/move_camera)
- 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)
- IO
- [Load file](https://codesandbox.io/p/sandbox/github/molstar/example-gallery/master/io/load_file)
- [Save session](https://codesandbox.io/p/sandbox/github/molstar/example-gallery/master/io/save_session)
Expand Down