mirror of
https://github.com/molstar/molstar.git
synced 2026-06-06 22:54:22 +08:00
Compare commits
85 Commits
v0.7.0-dev
...
v0.7.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1ece44c49 | ||
|
|
37ae274fb6 | ||
|
|
c900045fcd | ||
|
|
50d95ccf6a | ||
|
|
c9171444eb | ||
|
|
9e81626928 | ||
|
|
84fda6e35d | ||
|
|
0f758cf554 | ||
|
|
a6605052db | ||
|
|
8514175da2 | ||
|
|
6a49427fc0 | ||
|
|
7c18e5eb86 | ||
|
|
2a7d258715 | ||
|
|
54fb9beeee | ||
|
|
27ebbc50d5 | ||
|
|
2a1b6e52b2 | ||
|
|
3110e82d92 | ||
|
|
4be999ce32 | ||
|
|
f0d7a4ed2a | ||
|
|
2dacfcb485 | ||
|
|
6218cc5371 | ||
|
|
056ce42097 | ||
|
|
b14b5ca626 | ||
|
|
ffbaa944f2 | ||
|
|
e2ba96174a | ||
|
|
8c5d99bb54 | ||
|
|
b18b3be070 | ||
|
|
2e69b7c419 | ||
|
|
5007f5fb72 | ||
|
|
6fe83a9a70 | ||
|
|
20af084127 | ||
|
|
d6501170e6 | ||
|
|
5f33364514 | ||
|
|
7924c008fa | ||
|
|
2d2a53f28e | ||
|
|
1f7ffabef9 | ||
|
|
16d5c07224 | ||
|
|
2392bfb579 | ||
|
|
b4036f576c | ||
|
|
690d6812dc | ||
|
|
a44aa02f13 | ||
|
|
65ddd6d68a | ||
|
|
754025b3b1 | ||
|
|
f0649c5aa3 | ||
|
|
6df045211c | ||
|
|
8a00540de0 | ||
|
|
0d78905686 | ||
|
|
6edab203c2 | ||
|
|
0abfdb5ee3 | ||
|
|
88369158c9 | ||
|
|
8926575283 | ||
|
|
15b0288ce4 | ||
|
|
28853ec19d | ||
|
|
e3480a076a | ||
|
|
abf6452124 | ||
|
|
2cdd811dd3 | ||
|
|
be6fea39bf | ||
|
|
ed1bc2cd07 | ||
|
|
28d3d5861a | ||
|
|
95d3ef491f | ||
|
|
5c37ddfc6d | ||
|
|
4d9e2d9c91 | ||
|
|
0b1c18913d | ||
|
|
c8c2355d3e | ||
|
|
3d1366024d | ||
|
|
f6964d2a66 | ||
|
|
de60f70af5 | ||
|
|
8f2e619162 | ||
|
|
fbcef01c55 | ||
|
|
641e0639d4 | ||
|
|
5048573976 | ||
|
|
78e4d8536d | ||
|
|
a01d088205 | ||
|
|
4b1d1a045d | ||
|
|
e2857d00b4 | ||
|
|
a55a71d31a | ||
|
|
acf793f112 | ||
|
|
2d58ea28ea | ||
|
|
b21de78eb5 | ||
|
|
376d4b4ee1 | ||
|
|
e39304c7cf | ||
|
|
7cba9cda0c | ||
|
|
04c690e8f9 | ||
|
|
170d0fbc9d | ||
|
|
40d632a7b1 |
2637
package-lock.json
generated
2637
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
44
package.json
44
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "molstar",
|
||||
"version": "0.7.0-dev.3",
|
||||
"version": "0.7.0-dev.18",
|
||||
"description": "A comprehensive macromolecular library.",
|
||||
"homepage": "https://github.com/molstar/molstar#readme",
|
||||
"repository": {
|
||||
@@ -34,12 +34,12 @@
|
||||
"model-server-watch": "nodemon --watch lib lib/servers/servers/model/server.js",
|
||||
"volume-server-test": "node lib/servers/servers/volume/server.js --idMap em 'test/${id}.mdb' --defaultPort 1336",
|
||||
"plugin-state": "node lib/servers/servers/plugin-state/index.js",
|
||||
"preversion": "npm run test",
|
||||
"postversion": "git push && git push --tags",
|
||||
"prepublishOnly": "npm run test && npm run build"
|
||||
"preversion": "npm run test && npm run build",
|
||||
"postversion": "git push && git push --tags"
|
||||
},
|
||||
"files": [
|
||||
"lib/"
|
||||
"lib/",
|
||||
"build/viewer/"
|
||||
],
|
||||
"bin": {
|
||||
"cif2bcif": "lib/apps/cif2bcif/index.js",
|
||||
@@ -82,52 +82,52 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/add": "^1.13.2",
|
||||
"@graphql-codegen/cli": "^1.13.2",
|
||||
"@graphql-codegen/time": "^1.13.2",
|
||||
"@graphql-codegen/typescript": "^1.13.2",
|
||||
"@graphql-codegen/typescript-graphql-files-modules": "^1.13.2",
|
||||
"@graphql-codegen/typescript-graphql-request": "^1.13.2",
|
||||
"@graphql-codegen/typescript-operations": "^1.13.2",
|
||||
"@graphql-codegen/add": "^1.13.3",
|
||||
"@graphql-codegen/cli": "^1.13.3",
|
||||
"@graphql-codegen/time": "^1.13.3",
|
||||
"@graphql-codegen/typescript": "^1.13.3",
|
||||
"@graphql-codegen/typescript-graphql-files-modules": "^1.13.3",
|
||||
"@graphql-codegen/typescript-graphql-request": "^1.13.3",
|
||||
"@graphql-codegen/typescript-operations": "^1.13.3",
|
||||
"@types/cors": "^2.8.6",
|
||||
"@typescript-eslint/eslint-plugin": "^2.28.0",
|
||||
"@typescript-eslint/parser": "^2.28.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.29.0",
|
||||
"@typescript-eslint/parser": "^2.29.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"circular-dependency-plugin": "^5.2.0",
|
||||
"concurrently": "^5.1.0",
|
||||
"cpx2": "^2.0.0",
|
||||
"css-loader": "^3.5.2",
|
||||
"css-loader": "^3.5.3",
|
||||
"eslint": "^6.8.0",
|
||||
"extra-watch-webpack-plugin": "^1.0.3",
|
||||
"file-loader": "^6.0.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"graphql": "^15.0.0",
|
||||
"http-server": "^0.12.1",
|
||||
"jest": "^25.3.0",
|
||||
"jest": "^25.4.0",
|
||||
"jest-raw-loader": "^1.0.1",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"node-sass": "^4.13.1",
|
||||
"node-sass": "^4.14.0",
|
||||
"raw-loader": "^4.0.1",
|
||||
"resolve-url-loader": "^3.1.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"simple-git": "^1.132.0",
|
||||
"style-loader": "^1.1.4",
|
||||
"style-loader": "^1.2.0",
|
||||
"ts-jest": "^25.4.0",
|
||||
"typescript": "^3.8.3",
|
||||
"webpack": "^4.42.1",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"webpack-version-file-plugin": "^0.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@material-ui/core": "^4.9.10",
|
||||
"@material-ui/core": "^4.9.11",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@types/argparse": "^1.0.38",
|
||||
"@types/benchmark": "^1.0.31",
|
||||
"@types/compression": "1.7.0",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/jest": "^25.2.1",
|
||||
"@types/node": "^13.13.0",
|
||||
"@types/node-fetch": "^2.5.6",
|
||||
"@types/node": "^13.13.2",
|
||||
"@types/node-fetch": "^2.5.7",
|
||||
"@types/react": "^16.9.34",
|
||||
"@types/react-dom": "^16.9.6",
|
||||
"@types/swagger-ui-dist": "3.0.5",
|
||||
|
||||
@@ -117,7 +117,7 @@ export function printSequence(model: Model) {
|
||||
for (const key of Object.keys(byEntityKey)) {
|
||||
const { sequence, entityId } = byEntityKey[+key];
|
||||
const { seqId, compId } = sequence;
|
||||
console.log(`${entityId} (${sequence.kind} ${seqId.value(0)} (offset ${sequence.offset}), ${seqId.value(seqId.rowCount - 1)}) (${compId.value(0)}, ${compId.value(compId.rowCount - 1)})`);
|
||||
console.log(`${entityId} (${sequence.kind} ${seqId.value(0)}, ${seqId.value(seqId.rowCount - 1)}) (${compId.value(0)}, ${compId.value(compId.rowCount - 1)})`);
|
||||
console.log(`${Sequence.getSequenceString(sequence)}`);
|
||||
}
|
||||
console.log();
|
||||
|
||||
@@ -8,38 +8,36 @@ import * as fs from 'fs';
|
||||
import * as argparse from 'argparse';
|
||||
import * as util from 'util';
|
||||
|
||||
import { VolumeData, VolumeIsoValue } from '../../mol-model/volume';
|
||||
import { Volume } from '../../mol-model/volume';
|
||||
import { downloadCif } from './helpers';
|
||||
import { CIF } from '../../mol-io/reader/cif';
|
||||
import { DensityServer_Data_Database } from '../../mol-io/reader/cif/schema/density-server';
|
||||
import { Table } from '../../mol-data/db';
|
||||
import { StringBuilder } from '../../mol-util';
|
||||
import { Task } from '../../mol-task';
|
||||
import { createVolumeIsosurfaceMesh } from '../../mol-repr/volume/isosurface';
|
||||
import { Theme } from '../../mol-theme/theme';
|
||||
import { volumeFromDensityServerData } from '../../mol-model-formats/volume/density-server';
|
||||
import { volumeFromDensityServerData, DscifFormat } from '../../mol-model-formats/volume/density-server';
|
||||
|
||||
require('util.promisify').shim();
|
||||
const writeFileAsync = util.promisify(fs.writeFile);
|
||||
|
||||
type Volume = { source: DensityServer_Data_Database, volume: VolumeData }
|
||||
|
||||
async function getVolume(url: string): Promise<Volume> {
|
||||
const cif = await downloadCif(url, true);
|
||||
const data = CIF.schema.densityServer(cif.blocks[1]);
|
||||
return { source: data, volume: await volumeFromDensityServerData(data).run() };
|
||||
return await volumeFromDensityServerData(data).run();
|
||||
}
|
||||
|
||||
function print(data: Volume) {
|
||||
const { volume_data_3d_info } = data.source;
|
||||
function print(volume: Volume) {
|
||||
if (!DscifFormat.is(volume.sourceData)) return;
|
||||
const { volume_data_3d_info } = volume.sourceData.data;
|
||||
const row = Table.getRow(volume_data_3d_info, 0);
|
||||
console.log(row);
|
||||
if (data.volume.transform) console.log(data.volume.transform);
|
||||
console.log(data.volume.dataStats);
|
||||
console.log(volume.grid.transform);
|
||||
console.log(volume.grid.stats);
|
||||
}
|
||||
|
||||
async function doMesh(data: Volume, filename: string) {
|
||||
const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, data.volume, Theme.createEmpty(), { isoValue: VolumeIsoValue.absolute(1.5) } )).run();
|
||||
async function doMesh(volume: Volume, filename: string) {
|
||||
const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, volume, Theme.createEmpty(), { isoValue: Volume.IsoValue.absolute(1.5) } )).run();
|
||||
console.log({ vc: mesh.vertexCount, tc: mesh.triangleCount });
|
||||
|
||||
// Export the mesh in OBJ format.
|
||||
|
||||
63
src/apps/viewer/embedded.html
Normal file
63
src/apps/viewer/embedded.html
Normal file
@@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<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 {
|
||||
position: absolute;
|
||||
left: 100px;
|
||||
top: 100px;
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="molstar.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="text/javascript" src="./molstar.js"></script>
|
||||
<script type="text/javascript">
|
||||
var viewer = new molstar.Viewer('app', {
|
||||
layoutIsExpanded: false,
|
||||
layoutShowControls: false,
|
||||
layoutShowRemoteState: false,
|
||||
layoutShowSequence: true,
|
||||
layoutShowLog: false,
|
||||
layoutShowLeftPanel: true,
|
||||
|
||||
viewportShowExpand: true,
|
||||
viewportShowSelectionMode: false,
|
||||
viewportShowAnimation: false,
|
||||
|
||||
pdbProvider: 'rcsb',
|
||||
emdbProvider: 'rcsb',
|
||||
});
|
||||
viewer.loadPdb('7bv2');
|
||||
viewer.loadEmdb('EMD-30210');
|
||||
|
||||
// TODO add Volume.customProperty and load suggested isoValue via custom property
|
||||
var sub = viewer.plugin.managers.volume.hierarchy.behaviors.selection.subscribe(function (value) {
|
||||
if (value.volume?.representations[0]) {
|
||||
var ref = value.volume.representations[0].cell;
|
||||
var tree = viewer.plugin.state.data.build().to(ref).update({
|
||||
type: {
|
||||
name: 'isosurface',
|
||||
params: {
|
||||
isoValue: {
|
||||
kind: 'relative',
|
||||
relativeValue: 6
|
||||
}
|
||||
}
|
||||
},
|
||||
colorTheme: ref.transform.params?.colorTheme
|
||||
});
|
||||
viewer.plugin.runTask(viewer.plugin.state.data.updateTree(tree));
|
||||
if (typeof sub !== 'undefined') sub.unsubscribe();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -34,10 +34,43 @@
|
||||
height: 600px;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="app.css" />
|
||||
<link rel="stylesheet" type="text/css" href="molstar.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="text/javascript" src="./index.js"></script>
|
||||
<script type="text/javascript" src="./molstar.js"></script>
|
||||
<script type="text/javascript">
|
||||
function getParam(name, regex) {
|
||||
var r = new RegExp(name + '=' + '(' + regex + ')[&]?', 'i');
|
||||
return decodeURIComponent(((window.location.search || '').match(r) || [])[1] || '');
|
||||
}
|
||||
|
||||
var hideControls = getParam('hide-controls', '[^&]+').trim() === '1';
|
||||
var viewer = new molstar.Viewer('app', {
|
||||
layoutShowControls: !hideControls,
|
||||
viewportShowExpand: false,
|
||||
});
|
||||
|
||||
var snapshotId = getParam('snapshot-id', '[^&]+').trim();
|
||||
if (snapshotId) viewer.setRemoteSnapshot(snapshotId);
|
||||
|
||||
var snapshotUrl = getParam('snapshot-url', '[^&]+').trim();
|
||||
var snapshotUrlType = getParam('snapshot-url-type', '[^&]+').toLowerCase().trim();
|
||||
if (snapshotUrl && snapshotUrlType) viewer.loadSnapshotFromUrl(snapshotUrl, snapshotUrlType);
|
||||
|
||||
var structureUrl = getParam('structure-url', '[^&]+').trim();
|
||||
var structureUrlFormat = getParam('structure-url-format', '[a-z]+').toLowerCase().trim();
|
||||
var structureUrlIsBinary = getParam('structure-url-is-binary', '[^&]+').trim() === '1';
|
||||
if (structureUrl) viewer.loadStructureFromUrl(structureUrl, structureUrlFormat, structureUrlIsBinary);
|
||||
|
||||
var pdb = getParam('pdb', '[^&]+').trim();
|
||||
if (pdb) viewer.loadPdb(pdb);
|
||||
|
||||
var pdbDev = getParam('pdb-dev', '[^&]+').trim();
|
||||
if (pdbDev) viewer.loadPdbDev(pdbDev);
|
||||
|
||||
var emdb = getParam('emdb', '[^&]+').trim();
|
||||
if (emdb) viewer.loadEmdb(emdb);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -8,84 +8,110 @@
|
||||
import '../../mol-util/polyfill';
|
||||
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
|
||||
import './index.html';
|
||||
import './embedded.html';
|
||||
import './favicon.ico';
|
||||
import { PluginContext } from '../../mol-plugin/context';
|
||||
import { PluginCommands } from '../../mol-plugin/commands';
|
||||
import { PluginSpec } from '../../mol-plugin/spec';
|
||||
import { DownloadStructure } from '../../mol-plugin-state/actions/structure';
|
||||
import { DownloadStructure, PdbDownloadProvider } from '../../mol-plugin-state/actions/structure';
|
||||
import { PluginConfig } from '../../mol-plugin/config';
|
||||
import { CellPack } from '../../extensions/cellpack';
|
||||
import { RCSBAssemblySymmetry, RCSBValidationReport } from '../../extensions/rcsb';
|
||||
import { PDBeStructureQualityReport } from '../../extensions/pdbe';
|
||||
import { Asset } from '../../mol-util/assets';
|
||||
import { ObjectKeys } from '../../mol-util/type-helpers';
|
||||
import { PluginState } from '../../mol-plugin/state';
|
||||
import { DownloadDensity } from '../../mol-plugin-state/actions/volume';
|
||||
import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout';
|
||||
require('mol-plugin-ui/skin/light.scss');
|
||||
|
||||
function getParam(name: string, regex: string): string {
|
||||
let r = new RegExp(`${name}=(${regex})[&]?`, 'i');
|
||||
return decodeURIComponent(((window.location.search || '').match(r) || [])[1] || '');
|
||||
}
|
||||
const Extensions = {
|
||||
'cellpack': PluginSpec.Behavior(CellPack),
|
||||
'pdbe-structure-quality-report': PluginSpec.Behavior(PDBeStructureQualityReport),
|
||||
'rcsb-assembly-symmetry': PluginSpec.Behavior(RCSBAssemblySymmetry),
|
||||
'rcsb-validation-report': PluginSpec.Behavior(RCSBValidationReport)
|
||||
};
|
||||
|
||||
const hideControls = getParam('hide-controls', `[^&]+`) === '1';
|
||||
const DefaultViewerOptions = {
|
||||
extensions: ObjectKeys(Extensions),
|
||||
layoutIsExpanded: true,
|
||||
layoutShowControls: true,
|
||||
layoutShowRemoteState: true,
|
||||
layoutControlsDisplay: 'reactive' as PluginLayoutControlsDisplay,
|
||||
layoutShowSequence: true,
|
||||
layoutShowLog: true,
|
||||
layoutShowLeftPanel: true,
|
||||
|
||||
function init() {
|
||||
const spec: PluginSpec = {
|
||||
actions: [...DefaultPluginSpec.actions],
|
||||
behaviors: [
|
||||
...DefaultPluginSpec.behaviors,
|
||||
PluginSpec.Behavior(CellPack),
|
||||
PluginSpec.Behavior(PDBeStructureQualityReport),
|
||||
PluginSpec.Behavior(RCSBAssemblySymmetry),
|
||||
PluginSpec.Behavior(RCSBValidationReport),
|
||||
],
|
||||
animations: [...DefaultPluginSpec.animations || []],
|
||||
customParamEditors: DefaultPluginSpec.customParamEditors,
|
||||
layout: {
|
||||
initial: {
|
||||
isExpanded: true,
|
||||
showControls: !hideControls
|
||||
viewportShowExpand: PluginConfig.Viewport.ShowExpand.defaultValue,
|
||||
viewportShowSelectionMode: PluginConfig.Viewport.ShowSelectionMode.defaultValue,
|
||||
viewportShowAnimation: PluginConfig.Viewport.ShowAnimation.defaultValue,
|
||||
pluginStateServer: PluginConfig.State.DefaultServer.defaultValue,
|
||||
volumeStreamingServer: PluginConfig.VolumeStreaming.DefaultServer.defaultValue,
|
||||
pdbProvider: PluginConfig.Download.DefaultPdbProvider.defaultValue,
|
||||
emdbProvider: PluginConfig.Download.DefaultEmdbProvider.defaultValue,
|
||||
};
|
||||
type ViewerOptions = typeof DefaultViewerOptions;
|
||||
|
||||
export class Viewer {
|
||||
plugin: PluginContext
|
||||
|
||||
constructor(elementId: string, options: Partial<ViewerOptions> = {}) {
|
||||
const o = { ...DefaultViewerOptions, ...options };
|
||||
|
||||
const spec: PluginSpec = {
|
||||
actions: [...DefaultPluginSpec.actions],
|
||||
behaviors: [
|
||||
...DefaultPluginSpec.behaviors,
|
||||
...o.extensions.map(e => Extensions[e]),
|
||||
],
|
||||
animations: [...DefaultPluginSpec.animations || []],
|
||||
customParamEditors: DefaultPluginSpec.customParamEditors,
|
||||
layout: {
|
||||
initial: {
|
||||
isExpanded: o.layoutIsExpanded,
|
||||
showControls: o.layoutShowControls,
|
||||
controlsDisplay: o.layoutControlsDisplay,
|
||||
},
|
||||
controls: {
|
||||
...DefaultPluginSpec.layout && DefaultPluginSpec.layout.controls,
|
||||
top: o.layoutShowSequence ? undefined : 'none',
|
||||
bottom: o.layoutShowLog ? undefined : 'none',
|
||||
left: o.layoutShowLeftPanel ? undefined : 'none',
|
||||
}
|
||||
},
|
||||
controls: {
|
||||
...DefaultPluginSpec.layout && DefaultPluginSpec.layout.controls
|
||||
}
|
||||
},
|
||||
config: DefaultPluginSpec.config
|
||||
};
|
||||
spec.config?.set(PluginConfig.Viewport.ShowExpand, false);
|
||||
const plugin = createPlugin(document.getElementById('app')!, spec);
|
||||
trySetSnapshot(plugin);
|
||||
tryLoadFromUrl(plugin);
|
||||
}
|
||||
components: {
|
||||
...DefaultPluginSpec.components,
|
||||
remoteState: o.layoutShowRemoteState ? 'default' : 'none',
|
||||
},
|
||||
config: DefaultPluginSpec.config
|
||||
};
|
||||
|
||||
async function trySetSnapshot(ctx: PluginContext) {
|
||||
try {
|
||||
const snapshotUrl = getParam('snapshot-url', `[^&]+`);
|
||||
const snapshotId = getParam('snapshot-id', `[^&]+`);
|
||||
if (!snapshotUrl && !snapshotId) return;
|
||||
// TODO parametrize the server
|
||||
const url = snapshotId
|
||||
? `https://webchem.ncbr.muni.cz/molstar-state/get/${snapshotId}`
|
||||
: snapshotUrl;
|
||||
await PluginCommands.State.Snapshots.Fetch(ctx, { url });
|
||||
} catch (e) {
|
||||
ctx.log.error('Failed to load snapshot.');
|
||||
console.warn('Failed to load snapshot', e);
|
||||
spec.config?.set(PluginConfig.Viewport.ShowExpand, o.viewportShowExpand);
|
||||
spec.config?.set(PluginConfig.Viewport.ShowSelectionMode, o.viewportShowSelectionMode);
|
||||
spec.config?.set(PluginConfig.Viewport.ShowAnimation, o.viewportShowAnimation);
|
||||
spec.config?.set(PluginConfig.State.DefaultServer, o.pluginStateServer);
|
||||
spec.config?.set(PluginConfig.State.CurrentServer, o.pluginStateServer);
|
||||
spec.config?.set(PluginConfig.VolumeStreaming.DefaultServer, o.volumeStreamingServer);
|
||||
spec.config?.set(PluginConfig.Download.DefaultPdbProvider, o.pdbProvider);
|
||||
spec.config?.set(PluginConfig.Download.DefaultEmdbProvider, o.emdbProvider);
|
||||
|
||||
const element = document.getElementById(elementId);
|
||||
if (!element) throw new Error(`Could not get element with id '${elementId}'`);
|
||||
this.plugin = createPlugin(element, spec);
|
||||
}
|
||||
}
|
||||
|
||||
async function tryLoadFromUrl(ctx: PluginContext) {
|
||||
const url = getParam('loadFromURL', '[^&]+').trim();
|
||||
try {
|
||||
if (!url) return;
|
||||
async setRemoteSnapshot(id: string) {
|
||||
const url = `${this.plugin.config.get(PluginConfig.State.CurrentServer)}/get/${id}`;
|
||||
await PluginCommands.State.Snapshots.Fetch(this.plugin, { url });
|
||||
}
|
||||
|
||||
let format = 'cif', isBinary = false;
|
||||
switch (getParam('loadFromURLFormat', '[a-z]+').toLocaleLowerCase().trim()) {
|
||||
case 'pdb': format = 'pdb'; break;
|
||||
case 'mmbcif': isBinary = true; break;
|
||||
}
|
||||
async loadSnapshotFromUrl(url: string, type: PluginState.SnapshotType) {
|
||||
await PluginCommands.State.Snapshots.OpenUrl(this.plugin, { url, type });
|
||||
}
|
||||
|
||||
const params = DownloadStructure.createDefaultParams(void 0 as any, ctx);
|
||||
|
||||
return ctx.runTask(ctx.state.data.applyAction(DownloadStructure, {
|
||||
async loadStructureFromUrl(url: string, format = 'cif', isBinary = false) {
|
||||
const params = DownloadStructure.createDefaultParams(this.plugin.state.data.root.obj!, this.plugin);
|
||||
return this.plugin.runTask(this.plugin.state.data.applyAction(DownloadStructure, {
|
||||
source: {
|
||||
name: 'url',
|
||||
params: {
|
||||
@@ -96,10 +122,54 @@ async function tryLoadFromUrl(ctx: PluginContext) {
|
||||
}
|
||||
}
|
||||
}));
|
||||
} catch (e) {
|
||||
ctx.log.error(`Failed to load from URL (${url})`);
|
||||
console.warn(`Failed to load from URL (${url})`, e);
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
async loadPdb(pdb: string) {
|
||||
const params = DownloadStructure.createDefaultParams(this.plugin.state.data.root.obj!, this.plugin);
|
||||
const provider = this.plugin.config.get(PluginConfig.Download.DefaultPdbProvider)!;
|
||||
return this.plugin.runTask(this.plugin.state.data.applyAction(DownloadStructure, {
|
||||
source: {
|
||||
name: 'pdb' as const,
|
||||
params: {
|
||||
provider: {
|
||||
id: pdb,
|
||||
server: {
|
||||
name: provider,
|
||||
params: PdbDownloadProvider[provider].defaultValue as any
|
||||
}
|
||||
},
|
||||
options: params.source.params.options,
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
async loadPdbDev(pdbDev: string) {
|
||||
const params = DownloadStructure.createDefaultParams(this.plugin.state.data.root.obj!, this.plugin);
|
||||
return this.plugin.runTask(this.plugin.state.data.applyAction(DownloadStructure, {
|
||||
source: {
|
||||
name: 'pdb-dev' as const,
|
||||
params: {
|
||||
id: pdbDev,
|
||||
options: params.source.params.options,
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
async loadEmdb(emdb: string) {
|
||||
const provider = this.plugin.config.get(PluginConfig.Download.DefaultEmdbProvider)!;
|
||||
return this.plugin.runTask(this.plugin.state.data.applyAction(DownloadDensity, {
|
||||
source: {
|
||||
name: 'pdb-emd-ds' as const,
|
||||
params: {
|
||||
provider: {
|
||||
id: emdb,
|
||||
server: provider,
|
||||
},
|
||||
detail: 3,
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="app.css" />
|
||||
<link rel="stylesheet" type="text/css" href="molstar.css" />
|
||||
<script type="text/javascript" src="./index.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
@@ -55,13 +55,13 @@
|
||||
</select>
|
||||
</div>
|
||||
<div id="app"></div>
|
||||
<script>
|
||||
<script>
|
||||
function $(id) { return document.getElementById(id); }
|
||||
|
||||
|
||||
var pdbId = '1grm', assemblyId= '1';
|
||||
var url = 'https://www.ebi.ac.uk/pdbe/static/entry/' + pdbId + '_updated.cif';
|
||||
var format = 'mmcif';
|
||||
|
||||
|
||||
$('url').value = url;
|
||||
$('url').onchange = function (e) { url = e.target.value; }
|
||||
$('assemblyId').value = assemblyId;
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
addHeader('Camera');
|
||||
addControl('Toggle Spin', () => BasicMolStarWrapper.toggleSpin());
|
||||
|
||||
|
||||
addSeparator();
|
||||
|
||||
addHeader('Animation');
|
||||
@@ -115,7 +115,7 @@
|
||||
addControl('Static Superposition', () => BasicMolStarWrapper.tests.staticSuperposition());
|
||||
addControl('Dynamic Superposition', () => BasicMolStarWrapper.tests.dynamicSuperposition());
|
||||
addControl('Validation Tooltip', () => BasicMolStarWrapper.tests.toggleValidationTooltip());
|
||||
|
||||
|
||||
addControl('Show Toasts', () => BasicMolStarWrapper.tests.showToasts());
|
||||
addControl('Hide Toasts', () => BasicMolStarWrapper.tests.hideToasts());
|
||||
|
||||
|
||||
@@ -38,16 +38,16 @@
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="app.css" />
|
||||
<link rel="stylesheet" type="text/css" href="molstar.css" />
|
||||
<script type="text/javascript" src="./index.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id='controls'></div>
|
||||
<div id="app"></div>
|
||||
<script>
|
||||
<script>
|
||||
LightingDemo.init('app')
|
||||
LightingDemo.load({ url: 'https://files.rcsb.org/download/1M07.cif', assemblyId: '1' })
|
||||
|
||||
|
||||
addHeader('Example PDB IDs');
|
||||
addControl('1M07', () => LightingDemo.load({ url: 'https://files.rcsb.org/download/1M07.cif', assemblyId: '1' }));
|
||||
addControl('6HY0', () => LightingDemo.load({ url: 'https://files.rcsb.org/download/6HY0.cif', assemblyId: '1' }));
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="app.css" />
|
||||
<link rel="stylesheet" type="text/css" href="molstar.css" />
|
||||
<script type="text/javascript" src="./index.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
@@ -65,7 +65,7 @@
|
||||
<div id="app"></div>
|
||||
<div id="volume-streaming-wrapper"></div>
|
||||
<script>
|
||||
// it might be a good idea to define these colors in a separate script file
|
||||
// it might be a good idea to define these colors in a separate script file
|
||||
var CustomColors = [0x00ff00, 0x0000ff];
|
||||
|
||||
// create an instance of the plugin
|
||||
@@ -74,11 +74,11 @@
|
||||
console.log('Wrapper version', MolStarProteopediaWrapper.VERSION_MAJOR, MolStarProteopediaWrapper.VERSION_MINOR);
|
||||
|
||||
function $(id) { return document.getElementById(id); }
|
||||
|
||||
|
||||
var pdbId = '1cbs', assemblyId= 'preferred', isBinary = true;
|
||||
var url = 'https://www.ebi.ac.uk/pdbe/entry-files/download/' + pdbId + '.bcif'
|
||||
var format = 'cif';
|
||||
|
||||
|
||||
$('url').value = url;
|
||||
$('url').onchange = function (e) { url = e.target.value; }
|
||||
$('assemblyId').value = assemblyId;
|
||||
@@ -92,6 +92,12 @@
|
||||
// var format = 'pdb';
|
||||
// var assemblyId = 'deposited';
|
||||
|
||||
function loadAndSnapshot(params) {
|
||||
PluginWrapper.load(params).then(() => {
|
||||
setTimeout(() => snapshot = PluginWrapper.plugin.state.getSnapshot({ canvas3d: false /* do not save spinning state */ }), 500);
|
||||
});
|
||||
}
|
||||
|
||||
var representationStyle = {
|
||||
// sequence: { coloring: 'proteopedia-custom' }, // or just { }
|
||||
hetGroups: { kind: 'ball-and-stick' }, // or 'spacefill
|
||||
@@ -103,7 +109,7 @@
|
||||
customColorList: CustomColors
|
||||
});
|
||||
PluginWrapper.setBackground(0xffffff);
|
||||
PluginWrapper.load({ url: url, format: format, isBinary: isBinary, assemblyId: assemblyId, representationStyle: representationStyle });
|
||||
loadAndSnapshot({ url: url, format: format, isBinary: isBinary, assemblyId: assemblyId, representationStyle: representationStyle });
|
||||
PluginWrapper.toggleSpin();
|
||||
|
||||
PluginWrapper.events.modelInfo.subscribe(function (info) {
|
||||
@@ -111,8 +117,8 @@
|
||||
listHetGroups(info);
|
||||
});
|
||||
|
||||
addControl('Load Asym Unit', () => PluginWrapper.load({ url: url, format: format, isBinary }));
|
||||
addControl('Load Assembly', () => PluginWrapper.load({ url: url, format: format, isBinary, assemblyId: assemblyId }));
|
||||
addControl('Load Asym Unit', () => loadAndSnapshot({ url: url, format: format, isBinary }));
|
||||
addControl('Load Assembly', () => loadAndSnapshot({ url: url, format: format, isBinary, assemblyId: assemblyId }));
|
||||
|
||||
addSeparator();
|
||||
|
||||
@@ -138,7 +144,7 @@
|
||||
// Same as "wheel icon" and Viewport options
|
||||
// addControl('Clip', () => PluginWrapper.viewport.setSettings({ clip: [33, 66] }));
|
||||
// addControl('Reset Clip', () => PluginWrapper.viewport.setSettings({ clip: [1, 100] }));
|
||||
|
||||
|
||||
addSeparator();
|
||||
|
||||
addHeader('Animation');
|
||||
@@ -171,7 +177,7 @@
|
||||
addControl('Init', () => PluginWrapper.experimentalData.init($('volume-streaming-wrapper')));
|
||||
addControl('Remove', () => PluginWrapper.experimentalData.remove());
|
||||
|
||||
addSeparator();
|
||||
addSeparator();
|
||||
addHeader('State');
|
||||
|
||||
var snapshot;
|
||||
@@ -185,10 +191,10 @@
|
||||
PluginWrapper.snapshot.set(snapshot);
|
||||
});
|
||||
addControl('Download State', () => {
|
||||
snapshot = PluginWrapper.snapshot.download('molj');
|
||||
PluginWrapper.snapshot.download('molj');
|
||||
});
|
||||
addControl('Download Session', () => {
|
||||
snapshot = PluginWrapper.snapshot.download('molx');
|
||||
PluginWrapper.snapshot.download('molx');
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
@@ -5,35 +5,34 @@
|
||||
*/
|
||||
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { Canvas3DProps, DefaultCanvas3DParams } from '../../mol-canvas3d/canvas3d';
|
||||
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
|
||||
import './index.html';
|
||||
import { PluginContext } from '../../mol-plugin/context';
|
||||
import { PluginCommands } from '../../mol-plugin/commands';
|
||||
import { StateTransforms } from '../../mol-plugin-state/transforms';
|
||||
import { Color } from '../../mol-util/color';
|
||||
import { PluginStateObject as PSO, PluginStateObject } from '../../mol-plugin-state/objects';
|
||||
import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in';
|
||||
import { StateBuilder, StateObject, StateSelection } from '../../mol-state';
|
||||
import { EvolutionaryConservation } from './annotation';
|
||||
import { LoadParams, SupportedFormats, RepresentationStyle, ModelInfo, StateElements } from './helpers';
|
||||
import { RxEventHelper } from '../../mol-util/rx-event-helper';
|
||||
import { volumeStreamingControls } from './ui/controls';
|
||||
import { PluginState } from '../../mol-plugin/state';
|
||||
import { Scheduler } from '../../mol-task';
|
||||
import { createProteopediaCustomTheme } from './coloring';
|
||||
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
|
||||
import { ColorNames } from '../../mol-util/color/names';
|
||||
import { InitVolumeStreaming, CreateVolumeStreamingInfo } from '../../mol-plugin/behavior/dynamic/volume-streaming/transformers';
|
||||
import { DefaultCanvas3DParams, Canvas3DProps } from '../../mol-canvas3d/canvas3d';
|
||||
import { createStructureRepresentationParams } from '../../mol-plugin-state/helpers/structure-representation-params';
|
||||
import { download } from '../../mol-util/download';
|
||||
import { getFormattedTime } from '../../mol-util/date';
|
||||
import { PluginStateObject, PluginStateObject as PSO } from '../../mol-plugin-state/objects';
|
||||
import { StateTransforms } from '../../mol-plugin-state/transforms';
|
||||
import { CreateVolumeStreamingInfo, InitVolumeStreaming } from '../../mol-plugin/behavior/dynamic/volume-streaming/transformers';
|
||||
import { PluginCommands } from '../../mol-plugin/commands';
|
||||
import { PluginContext } from '../../mol-plugin/context';
|
||||
import { PluginState } from '../../mol-plugin/state';
|
||||
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
|
||||
import { StateBuilder, StateObject, StateSelection } from '../../mol-state';
|
||||
import { Asset } from '../../mol-util/assets';
|
||||
import { Color } from '../../mol-util/color';
|
||||
import { ColorNames } from '../../mol-util/color/names';
|
||||
import { getFormattedTime } from '../../mol-util/date';
|
||||
import { download } from '../../mol-util/download';
|
||||
import { RxEventHelper } from '../../mol-util/rx-event-helper';
|
||||
import { EvolutionaryConservation } from './annotation';
|
||||
import { createProteopediaCustomTheme } from './coloring';
|
||||
import { LoadParams, ModelInfo, RepresentationStyle, StateElements, SupportedFormats } from './helpers';
|
||||
import './index.html';
|
||||
import { volumeStreamingControls } from './ui/controls';
|
||||
require('../../mol-plugin-ui/skin/light.scss');
|
||||
|
||||
class MolStarProteopediaWrapper {
|
||||
static VERSION_MAJOR = 5;
|
||||
static VERSION_MINOR = 4;
|
||||
static VERSION_MINOR = 5;
|
||||
|
||||
private _ev = RxEventHelper.create();
|
||||
|
||||
@@ -233,7 +232,6 @@ class MolStarProteopediaWrapper {
|
||||
await this.updateStyle(representationStyle);
|
||||
|
||||
this.loadedParams = { url, format, assemblyId };
|
||||
Scheduler.setImmediate(() => PluginCommands.Camera.Reset(this.plugin, { }));
|
||||
}
|
||||
|
||||
async updateStyle(style?: RepresentationStyle, partial?: boolean) {
|
||||
@@ -407,7 +405,7 @@ class MolStarProteopediaWrapper {
|
||||
try {
|
||||
const data = await this.plugin.runTask(this.plugin.fetch({ url, type: 'binary' }));
|
||||
this.loadedParams = { ...this.emptyLoadedParams };
|
||||
await this.plugin.managers.snapshot.open(new File([data], `state.${type}`));
|
||||
return await this.plugin.managers.snapshot.open(new File([data], `state.${type}`));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
@@ -27,61 +27,75 @@ import { Column } from '../../mol-data/db';
|
||||
import { createModels } from '../../mol-model-formats/structure/basic/parser';
|
||||
import { CellpackPackingPreset, CellpackMembranePreset } from './preset';
|
||||
import { Asset } from '../../mol-util/assets';
|
||||
import { readFromFile } from '../../mol-util/data-source';
|
||||
import { objectForEach } from '../../mol-util/object';
|
||||
|
||||
function getCellPackModelUrl(fileName: string, baseUrl: string) {
|
||||
return `${baseUrl}/results/${fileName}`;
|
||||
}
|
||||
|
||||
async function getModel(plugin: PluginContext, id: string, ingredient: Ingredient, baseUrl: string, file?: Asset.File) {
|
||||
class TrajectoryCache {
|
||||
private map = new Map<string, Model.Trajectory>();
|
||||
set(id: string, trajectory: Model.Trajectory) { this.map.set(id, trajectory); }
|
||||
get(id: string) { return this.map.get(id); }
|
||||
}
|
||||
|
||||
async function getModel(plugin: PluginContext, id: string, ingredient: Ingredient, baseUrl: string, trajCache: TrajectoryCache, file?: Asset.File) {
|
||||
const assetManager = plugin.managers.asset;
|
||||
const model_id = (ingredient.source.model) ? parseInt(ingredient.source.model) : 0;
|
||||
const modelIndex = (ingredient.source.model) ? parseInt(ingredient.source.model) : 0;
|
||||
const surface = (ingredient.ingtype) ? (ingredient.ingtype === 'transmembrane') : false;
|
||||
let model: Model;
|
||||
let trajectory = trajCache.get(id);
|
||||
let assets: Asset.Wrapper[] = [];
|
||||
if (file) {
|
||||
if (file.name.endsWith('.cif')) {
|
||||
const text = await plugin.runTask(assetManager.resolve(file, 'string'));
|
||||
assets.push(text);
|
||||
const cif = (await parseCif(plugin, text.data)).blocks[0];
|
||||
model = (await plugin.runTask(trajectoryFromMmCIF(cif)))[model_id];
|
||||
} else if (file.name.endsWith('.bcif')) {
|
||||
const binary = await plugin.runTask(assetManager.resolve(file, 'binary'));
|
||||
assets.push(binary);
|
||||
const cif = (await parseCif(plugin, binary.data)).blocks[0];
|
||||
model = (await plugin.runTask(trajectoryFromMmCIF(cif)))[model_id];
|
||||
} else if (file.name.endsWith('.pdb')) {
|
||||
const text = await plugin.runTask(assetManager.resolve(file, 'string'));
|
||||
assets.push(text);
|
||||
const pdb = await parsePDBfile(plugin, text.data, id);
|
||||
model = (await plugin.runTask(trajectoryFromPDB(pdb)))[model_id];
|
||||
} else {
|
||||
throw new Error(`unsupported file type '${file.name}'`);
|
||||
}
|
||||
} else if (id.match(/^[1-9][a-zA-Z0-9]{3,3}$/i)) {
|
||||
if (surface){
|
||||
const data = await getFromOPM(plugin, id, assetManager);
|
||||
if (data.asset){
|
||||
assets.push(data.asset);
|
||||
model = (await plugin.runTask(trajectoryFromPDB(data.pdb)))[model_id];
|
||||
if (!trajectory) {
|
||||
if (file) {
|
||||
if (file.name.endsWith('.cif')) {
|
||||
const text = await plugin.runTask(assetManager.resolve(file, 'string'));
|
||||
assets.push(text);
|
||||
const cif = (await parseCif(plugin, text.data)).blocks[0];
|
||||
trajectory = await plugin.runTask(trajectoryFromMmCIF(cif));
|
||||
} else if (file.name.endsWith('.bcif')) {
|
||||
const binary = await plugin.runTask(assetManager.resolve(file, 'binary'));
|
||||
assets.push(binary);
|
||||
const cif = (await parseCif(plugin, binary.data)).blocks[0];
|
||||
trajectory = await plugin.runTask(trajectoryFromMmCIF(cif));
|
||||
} else if (file.name.endsWith('.pdb')) {
|
||||
const text = await plugin.runTask(assetManager.resolve(file, 'string'));
|
||||
assets.push(text);
|
||||
const pdb = await parsePDBfile(plugin, text.data, id);
|
||||
trajectory = await plugin.runTask(trajectoryFromPDB(pdb));
|
||||
} else {
|
||||
throw new Error(`unsupported file type '${file.name}'`);
|
||||
}
|
||||
} else if (id.match(/^[1-9][a-zA-Z0-9]{3,3}$/i)) {
|
||||
if (surface){
|
||||
try {
|
||||
const data = await getFromOPM(plugin, id, assetManager);
|
||||
assets.push(data.asset);
|
||||
trajectory = await plugin.runTask(trajectoryFromPDB(data.pdb));
|
||||
} catch (e) {
|
||||
// fallback to getFromPdb
|
||||
// console.error(e);
|
||||
const { mmcif, asset } = await getFromPdb(plugin, id, assetManager);
|
||||
assets.push(asset);
|
||||
trajectory = await plugin.runTask(trajectoryFromMmCIF(mmcif));
|
||||
}
|
||||
} else {
|
||||
const { mmcif, asset } = await getFromPdb(plugin, id, assetManager);
|
||||
assets.push(asset);
|
||||
model = (await plugin.runTask(trajectoryFromMmCIF(mmcif)))[model_id];
|
||||
trajectory = await plugin.runTask(trajectoryFromMmCIF(mmcif));
|
||||
}
|
||||
} else {
|
||||
const { mmcif, asset } = await getFromPdb(plugin, id, assetManager);
|
||||
assets.push(asset);
|
||||
model = (await plugin.runTask(trajectoryFromMmCIF(mmcif)))[model_id];
|
||||
}
|
||||
} else {
|
||||
const data = await getFromCellPackDB(plugin, id, baseUrl, assetManager);
|
||||
assets.push(data.asset);
|
||||
if ('pdb' in data) {
|
||||
model = (await plugin.runTask(trajectoryFromPDB(data.pdb)))[model_id];
|
||||
} else {
|
||||
model = (await plugin.runTask(trajectoryFromMmCIF(data.mmcif)))[model_id];
|
||||
const data = await getFromCellPackDB(plugin, id, baseUrl, assetManager);
|
||||
assets.push(data.asset);
|
||||
if ('pdb' in data) {
|
||||
trajectory = await plugin.runTask(trajectoryFromPDB(data.pdb));
|
||||
} else {
|
||||
trajectory = await plugin.runTask(trajectoryFromMmCIF(data.mmcif));
|
||||
}
|
||||
}
|
||||
trajCache.set(id, trajectory);
|
||||
}
|
||||
const model = trajectory[modelIndex];
|
||||
return { model, assets };
|
||||
}
|
||||
|
||||
@@ -133,7 +147,6 @@ function getTransform(trans: Vec3, rot: Quat) {
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
function getResultTransforms(results: Ingredient['results'], legacy: boolean) {
|
||||
if (legacy) return results.map((r: Ingredient['results'][0]) => getTransformLegacy(r[0], r[1]));
|
||||
else return results.map((r: Ingredient['results'][0]) => getTransform(r[0], r[1]));
|
||||
@@ -288,7 +301,7 @@ async function getCurve(plugin: PluginContext, name: string, ingredient: Ingredi
|
||||
return getStructure(plugin, curveModel, ingredient.source);
|
||||
}
|
||||
|
||||
async function getIngredientStructure(plugin: PluginContext, ingredient: Ingredient, baseUrl: string, ingredientFiles: IngredientFiles) {
|
||||
async function getIngredientStructure(plugin: PluginContext, ingredient: Ingredient, baseUrl: string, ingredientFiles: IngredientFiles, trajCache: TrajectoryCache) {
|
||||
const { name, source, results, nbCurve } = ingredient;
|
||||
if (source.pdb === 'None') return;
|
||||
|
||||
@@ -303,7 +316,7 @@ async function getIngredientStructure(plugin: PluginContext, ingredient: Ingredi
|
||||
}
|
||||
|
||||
// model id in case structure is NMR
|
||||
const { model, assets } = await getModel(plugin, source.pdb || name, ingredient, baseUrl, file);
|
||||
const { model, assets } = await getModel(plugin, source.pdb || name, ingredient, baseUrl, trajCache, file);
|
||||
if (!model) return;
|
||||
|
||||
let structure: Structure;
|
||||
@@ -354,10 +367,11 @@ export function createStructureFromCellPack(plugin: PluginContext, packing: Cell
|
||||
return Task.create('Create Packing Structure', async ctx => {
|
||||
const { ingredients, name } = packing;
|
||||
const assets: Asset.Wrapper[] = [];
|
||||
const trajCache = new TrajectoryCache();
|
||||
const structures: Structure[] = [];
|
||||
for (const iName in ingredients) {
|
||||
if (ctx.shouldUpdate) await ctx.update(iName);
|
||||
const ingredientStructure = await getIngredientStructure(plugin, ingredients[iName], baseUrl, ingredientFiles);
|
||||
const ingredientStructure = await getIngredientStructure(plugin, ingredients[iName], baseUrl, ingredientFiles, trajCache);
|
||||
if (ingredientStructure) {
|
||||
structures.push(ingredientStructure.structure);
|
||||
assets.push(...ingredientStructure.assets);
|
||||
@@ -444,6 +458,8 @@ async function loadMembrane(plugin: PluginContext, name: string, state: State, p
|
||||
}
|
||||
|
||||
async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, state: State, params: LoadCellPackModelParams) {
|
||||
const ingredientFiles = params.ingredients.files || [];
|
||||
|
||||
let cellPackJson: StateBuilder.To<PSO.Format.Json, StateTransformer<PSO.Data.String, PSO.Format.Json>>;
|
||||
if (params.source.name === 'id') {
|
||||
const url = Asset.getUrlAsset(plugin.managers.asset, getCellPackModelUrl(params.source.params, params.baseUrl));
|
||||
@@ -451,12 +467,25 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat
|
||||
.apply(StateTransforms.Data.Download, { url, isBinary: false, label: params.source.params }, { state: { isGhost: true } });
|
||||
} else {
|
||||
const file = params.source.params;
|
||||
if (file === null) {
|
||||
if (!file?.file) {
|
||||
plugin.log.error('No file selected');
|
||||
return;
|
||||
}
|
||||
|
||||
let jsonFile: Asset.File;
|
||||
if (file.name.toLowerCase().endsWith('.zip')) {
|
||||
const data = await readFromFile(file.file, 'zip').runInContext(runtime);
|
||||
jsonFile = Asset.File(new File([data['model.json']], 'model.json'));
|
||||
objectForEach(data, (v, k) => {
|
||||
if (k === 'model.json') return;
|
||||
ingredientFiles.push(Asset.File(new File([v], k)));
|
||||
});
|
||||
} else {
|
||||
jsonFile = file;
|
||||
}
|
||||
|
||||
cellPackJson = state.build().toRoot()
|
||||
.apply(StateTransforms.Data.ReadFile, { file, isBinary: false, label: file.name }, { state: { isGhost: true } });
|
||||
.apply(StateTransforms.Data.ReadFile, { file: jsonFile, isBinary: false, label: jsonFile.name }, { state: { isGhost: true } });
|
||||
}
|
||||
|
||||
const cellPackBuilder = cellPackJson
|
||||
@@ -469,7 +498,7 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat
|
||||
await handleHivRna(plugin, packings, params.baseUrl);
|
||||
|
||||
for (let i = 0, il = packings.length; i < il; ++i) {
|
||||
const p = { packing: i, baseUrl: params.baseUrl, ingredientFiles: params.ingredients.files };
|
||||
const p = { packing: i, baseUrl: params.baseUrl, ingredientFiles };
|
||||
|
||||
const packing = await state.build()
|
||||
.to(cellPackBuilder.ref)
|
||||
@@ -497,8 +526,8 @@ const LoadCellPackModelParams = {
|
||||
['influenza_model1.json', 'influenza_model1'],
|
||||
['ExosomeModel.json', 'ExosomeModel'],
|
||||
['Mycoplasma1.5_mixed_pdb_fixed.cpr', 'Mycoplasma1.5_mixed_pdb_fixed'],
|
||||
] as const),
|
||||
'file': PD.File({ accept: 'id' }),
|
||||
] as const, { description: 'Download the model definition with `id` from the server at `baseUrl.`' }),
|
||||
'file': PD.File({ accept: '.json,.cpr,.zip', description: 'Open model definition from .json/.cpr file or open .zip file containing model definition plus ingredients.' }),
|
||||
}, { options: [['id', 'Id'], ['file', 'File']] }),
|
||||
baseUrl: PD.Text(DefaultCellPackBaseUrl),
|
||||
ingredients : PD.Group({
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
*/
|
||||
|
||||
import { CustomStructureProperty } from '../../mol-model-props/common/custom-structure-property';
|
||||
import { Structure, CustomPropertyDescriptor } from '../../mol-model/structure';
|
||||
import { Structure } from '../../mol-model/structure';
|
||||
import { CustomProperty } from '../../mol-model-props/common/custom-property';
|
||||
import { ParamDefinition as PD } from '../../mol-util/param-definition';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
|
||||
export type CellPackInfoValue = {
|
||||
packingsCount: number
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
import { Column, Table } from '../../mol-data/db';
|
||||
import { toTable } from '../../mol-io/reader/cif/schema';
|
||||
import { CifWriter } from '../../mol-io/writer/cif';
|
||||
import { Model, CustomPropertyDescriptor } from '../../mol-model/structure';
|
||||
import { Model } from '../../mol-model/structure';
|
||||
import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry';
|
||||
import { MmcifFormat } from '../../mol-model-formats/structure/mmcif';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
|
||||
export namespace PDBePreferredAssembly {
|
||||
export type Property = string
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
import { Column, Table } from '../../mol-data/db';
|
||||
import { toTable } from '../../mol-io/reader/cif/schema';
|
||||
import { CifWriter } from '../../mol-io/writer/cif';
|
||||
import { Model, CustomPropertyDescriptor } from '../../mol-model/structure';
|
||||
import { Model } from '../../mol-model/structure';
|
||||
import { PropertyWrapper } from '../../mol-model-props/common/wrapper';
|
||||
import { MmcifFormat } from '../../mol-model-formats/structure/mmcif';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
|
||||
export namespace PDBeStructRefDomain {
|
||||
export type Property = PropertyWrapper<Table<Schema['pdbe_struct_ref_domain']> | undefined>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Column, Table } from '../../../mol-data/db';
|
||||
import { toTable } from '../../../mol-io/reader/cif/schema';
|
||||
import { mmCIF_residueId_schema } from '../../../mol-io/reader/cif/schema/mmcif-extras';
|
||||
import { CifWriter } from '../../../mol-io/writer/cif';
|
||||
import { Model, CustomPropertyDescriptor, ResidueIndex, Unit, IndexedCustomProperty } from '../../../mol-model/structure';
|
||||
import { Model, ResidueIndex, Unit, IndexedCustomProperty } from '../../../mol-model/structure';
|
||||
import { residueIdFields } from '../../../mol-model/structure/export/categories/atom_site';
|
||||
import { StructureElement, CifExportContext, Structure } from '../../../mol-model/structure/structure';
|
||||
import { CustomPropSymbol } from '../../../mol-script/language/symbol';
|
||||
@@ -22,6 +22,7 @@ import { PropertyWrapper } from '../../../mol-model-props/common/wrapper';
|
||||
import { CustomProperty } from '../../../mol-model-props/common/custom-property';
|
||||
import { CustomModelProperty } from '../../../mol-model-props/common/custom-model-property';
|
||||
import { Asset } from '../../../mol-util/assets';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
|
||||
|
||||
export { StructureQualityReport };
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { AssemblySymmetryQuery, AssemblySymmetryQueryVariables } from '../graphq
|
||||
import query from '../graphql/symmetry.gql';
|
||||
|
||||
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
|
||||
import { CustomPropertyDescriptor, Structure, Model, StructureSelection, QueryContext } from '../../../mol-model/structure';
|
||||
import { Structure, Model, StructureSelection, QueryContext } from '../../../mol-model/structure';
|
||||
import { Database as _Database, Column } from '../../../mol-data/db';
|
||||
import { GraphQLClient } from '../../../mol-util/graphql-client';
|
||||
import { CustomProperty } from '../../../mol-model-props/common/custom-property';
|
||||
@@ -19,6 +19,7 @@ import { ReadonlyVec3 } from '../../../mol-math/linear-algebra/3d/vec3';
|
||||
import { SetUtils } from '../../../mol-util/set';
|
||||
import { MolScriptBuilder as MS } from '../../../mol-script/language/builder';
|
||||
import { compile } from '../../../mol-script/runtime/query/compiler';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
|
||||
|
||||
const BiologicalAssemblyNames = new Set([
|
||||
'author_and_software_defined_assembly',
|
||||
|
||||
@@ -225,6 +225,7 @@ function getSymbolScale(symbol: string) {
|
||||
function setSymbolTransform(t: Mat4, symbol: string, axes: AssemblySymmetry.RotationAxes, size: number, structure: Structure) {
|
||||
const eye = Vec3();
|
||||
const target = Vec3();
|
||||
const dir = Vec3();
|
||||
const up = Vec3();
|
||||
let pair: Mutable<AssemblySymmetry.RotationAxes> | undefined = undefined;
|
||||
|
||||
@@ -246,8 +247,8 @@ function setSymbolTransform(t: Mat4, symbol: string, axes: AssemblySymmetry.Rota
|
||||
const a5dir = Vec3.sub(Vec3(), a5.end, a5.start);
|
||||
pair = [a5];
|
||||
for (const a of axes.filter(a => a.order === 3)) {
|
||||
let d = radToDeg(Vec3.angle(Vec3.sub(up, a.end, a.start), a5dir));
|
||||
if (equalEps(d, 100.81, 0.1) || equalEps(d, 79.19, 0.1)) {
|
||||
const d = radToDeg(Vec3.angle(Vec3.sub(up, a.end, a.start), a5dir));
|
||||
if (!pair[1] && (equalEps(d, 100.81, 0.1) || equalEps(d, 79.19, 0.1))) {
|
||||
pair[1] = a;
|
||||
break;
|
||||
}
|
||||
@@ -263,8 +264,8 @@ function setSymbolTransform(t: Mat4, symbol: string, axes: AssemblySymmetry.Rota
|
||||
Vec3.copy(target, aA.end);
|
||||
if (aB) {
|
||||
Vec3.sub(up, aB.end, aB.start);
|
||||
const d = Vec3.dot(eye, up);
|
||||
if (d < 0) Vec3.negate(up, up);
|
||||
Vec3.sub(dir, eye, target);
|
||||
if (Vec3.dot(dir, up) < 0) Vec3.negate(up, up);
|
||||
Mat4.targetTo(t, eye, target, up);
|
||||
Mat4.scaleUniformly(t, t, size * getSymbolScale(symbol));
|
||||
} else {
|
||||
|
||||
@@ -340,7 +340,7 @@ export const ValidationReportDensityFitPreset = StructureRepresentationPresetPro
|
||||
description: 'Color structure based on density fit. Data from wwPDB Validation Report, obtained via RCSB PDB.'
|
||||
},
|
||||
isApplicable(a) {
|
||||
return a.data.models.length === 1 && ValidationReport.isApplicable(a.data.models[0]) && Model.hasXrayMap(a.data.models[0]);
|
||||
return a.data.models.length === 1 && ValidationReport.isApplicable(a.data.models[0]) && Model.isFromXray(a.data.models[0]) && Model.probablyHasDensityMap(a.data.models[0]);
|
||||
},
|
||||
params: () => StructureRepresentationPresetProvider.CommonParams,
|
||||
async apply(ref, params, plugin) {
|
||||
|
||||
@@ -67,7 +67,7 @@ export const DensityFitColorThemeProvider: ColorTheme.Provider<{}, ValidationRep
|
||||
factory: DensityFitColorTheme,
|
||||
getParams: () => ({}),
|
||||
defaultValues: PD.getDefaultValues({}),
|
||||
isApplicable: (ctx: ThemeDataContext) => !!ctx.structure && ValidationReport.isApplicable(ctx.structure.models[0]) && Model.hasXrayMap(ctx.structure.models[0]),
|
||||
isApplicable: (ctx: ThemeDataContext) => !!ctx.structure && ValidationReport.isApplicable(ctx.structure.models[0]) && Model.isFromXray(ctx.structure.models[0]) && Model.probablyHasDensityMap(ctx.structure.models[0]),
|
||||
ensureCustomProperties: {
|
||||
attach: (ctx: CustomProperty.Context, data: ThemeDataContext) => data.structure ? ValidationReportProvider.attach(ctx, data.structure.models[0], void 0, true) : Promise.resolve(),
|
||||
detach: (data) => data.structure && data.structure.models[0].customProperties.reference(ValidationReportProvider.descriptor, false)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
|
||||
import { CustomPropertyDescriptor, Structure, Unit } from '../../../mol-model/structure';
|
||||
import { Structure, Unit } from '../../../mol-model/structure';
|
||||
import { CustomProperty } from '../../../mol-model-props/common/custom-property';
|
||||
import { CustomModelProperty } from '../../../mol-model-props/common/custom-model-property';
|
||||
import { Model, ElementIndex, ResidueIndex } from '../../../mol-model/structure/model';
|
||||
@@ -21,6 +21,7 @@ import { QuerySymbolRuntime } from '../../../mol-script/runtime/query/compiler';
|
||||
import { CustomPropSymbol } from '../../../mol-script/language/symbol';
|
||||
import Type from '../../../mol-script/language/type';
|
||||
import { Asset } from '../../../mol-util/assets';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
|
||||
|
||||
export { ValidationReport };
|
||||
|
||||
|
||||
@@ -132,12 +132,12 @@ namespace Canvas3D {
|
||||
if (webgl.isContextLost) return;
|
||||
if (!e.shiftKey || !e.ctrlKey || !e.altKey) return;
|
||||
|
||||
console.log('lose context');
|
||||
if (isDebugMode) console.log('lose context');
|
||||
loseContextExt.loseContext();
|
||||
|
||||
setTimeout(() => {
|
||||
if (!webgl.isContextLost) return;
|
||||
console.log('restore context');
|
||||
if (isDebugMode) console.log('restore context');
|
||||
loseContextExt.restoreContext();
|
||||
}, 1000);
|
||||
}, false);
|
||||
|
||||
@@ -159,5 +159,5 @@ const instanceMaterialId = getNextMaterialId();
|
||||
|
||||
function createBoundingSphereRenderObject(mesh: Mesh, color: Color, materialId: number, transform?: TransformData) {
|
||||
const values = Mesh.Utils.createValuesSimple(mesh, { alpha: 0.1, doubleSided: false }, color, 1, transform);
|
||||
return createRenderObject('mesh', values, { visible: true, alphaFactor: 1, pickable: false, opaque: false }, materialId);
|
||||
return createRenderObject('mesh', values, { visible: true, alphaFactor: 1, pickable: false, opaque: false, writeDepth: false }, materialId);
|
||||
}
|
||||
@@ -59,7 +59,7 @@ export const PostprocessingParams = {
|
||||
outline: PD.MappedStatic('off', {
|
||||
on: PD.Group({
|
||||
scale: PD.Numeric(1, { min: 0, max: 10, step: 1 }),
|
||||
threshold: PD.Numeric(0.8, { min: 0, max: 1, step: 0.01 }),
|
||||
threshold: PD.Numeric(0.8, { min: 0, max: 5, step: 0.01 }),
|
||||
}),
|
||||
off: PD.Group({})
|
||||
}, { cycle: true, description: 'Draw outline around 3D objects' })
|
||||
|
||||
@@ -72,15 +72,18 @@ export namespace BaseGeometry {
|
||||
}
|
||||
|
||||
export function createRenderableState(props: Partial<PD.Values<Params>> = {}): RenderableState {
|
||||
const opaque = props.alpha === undefined ? true : props.alpha === 1;
|
||||
return {
|
||||
visible: true,
|
||||
alphaFactor: 1,
|
||||
pickable: true,
|
||||
opaque: props.alpha === undefined ? true : props.alpha === 1
|
||||
opaque,
|
||||
writeDepth: opaque,
|
||||
};
|
||||
}
|
||||
|
||||
export function updateRenderableState(state: RenderableState, props: PD.Values<Params>) {
|
||||
state.opaque = props.alpha * state.alphaFactor >= 1;
|
||||
state.writeDepth = state.opaque;
|
||||
}
|
||||
}
|
||||
@@ -98,8 +98,7 @@ namespace Image {
|
||||
return image;
|
||||
}
|
||||
|
||||
function update(imageTexture: TextureImage<Uint8Array | Float32Array>, corners: Float32Array, groupTexture: TextureImage<Float32Array>, image: Image): Image {
|
||||
|
||||
function update(imageTexture: TextureImage<Float32Array>, corners: Float32Array, groupTexture: TextureImage<Float32Array>, image: Image): Image {
|
||||
const width = imageTexture.width;
|
||||
const height = imageTexture.height;
|
||||
|
||||
@@ -116,7 +115,7 @@ namespace Image {
|
||||
|
||||
export const Params = {
|
||||
...BaseGeometry.Params,
|
||||
interpolation: PD.Select('bspline', PD.objectToOptions(InterpolationTypes), { isEssential: true }),
|
||||
interpolation: PD.Select('bspline', PD.objectToOptions(InterpolationTypes)),
|
||||
};
|
||||
export type Params = typeof Params
|
||||
|
||||
@@ -176,7 +175,7 @@ namespace Image {
|
||||
}
|
||||
|
||||
function updateValues(values: ImageValues, props: PD.Values<Params>) {
|
||||
ValueCell.updateIfChanged(values.uAlpha, props.alpha);
|
||||
BaseGeometry.updateValues(values, props);
|
||||
ValueCell.updateIfChanged(values.dInterpolation, props.interpolation);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ export function addTube(state: MeshBuilder.State, controlPoints: ArrayLike<numbe
|
||||
if (radialSegments === 2) {
|
||||
// add2AndScale2(normalVector, u, v, w * Math.cos(t), h * Math.sin(t))
|
||||
Vec3.copy(normalVector, v);
|
||||
console.log(i, t);
|
||||
Vec3.normalize(normalVector, normalVector);
|
||||
if (t !== 0 || i % 2 === 0) Vec3.negate(normalVector, normalVector);
|
||||
} else {
|
||||
|
||||
@@ -86,7 +86,8 @@ function createPoints() {
|
||||
visible: true,
|
||||
alphaFactor: 1,
|
||||
pickable: true,
|
||||
opaque: true
|
||||
opaque: true,
|
||||
writeDepth: true
|
||||
};
|
||||
|
||||
return createRenderObject('points', values, state, -1);
|
||||
|
||||
@@ -18,6 +18,7 @@ export type RenderableState = {
|
||||
alphaFactor: number
|
||||
pickable: boolean
|
||||
opaque: boolean
|
||||
writeDepth: boolean,
|
||||
}
|
||||
|
||||
export interface Renderable<T extends RenderableValues> {
|
||||
@@ -43,9 +44,6 @@ export function createRenderable<T extends Values<RenderableSchema>>(renderItem:
|
||||
if (values.uAlpha && values.alpha) {
|
||||
ValueCell.updateIfChanged(values.uAlpha, clamp(values.alpha.ref.value * state.alphaFactor, 0, 1));
|
||||
}
|
||||
if (values.uPickable) {
|
||||
ValueCell.updateIfChanged(values.uPickable, state.pickable ? 1 : 0);
|
||||
}
|
||||
renderItem.render(variant);
|
||||
},
|
||||
getProgram: (variant: GraphicsRenderVariant) => renderItem.getProgram(variant),
|
||||
|
||||
@@ -73,7 +73,6 @@ export function DirectVolumeRenderable(ctx: WebGLContext, id: number, values: Di
|
||||
const schema = { ...GlobalUniformSchema, ...InternalSchema, ...DirectVolumeSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
uPickable: ValueCell.create(state.pickable ? 1 : 0),
|
||||
};
|
||||
const shaderCode = DirectVolumeShaderCode;
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId);
|
||||
|
||||
@@ -33,7 +33,6 @@ export function ImageRenderable(ctx: WebGLContext, id: number, values: ImageValu
|
||||
const schema = { ...GlobalUniformSchema, ...InternalSchema, ...ImageSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
uPickable: ValueCell.create(state.pickable ? 1 : 0),
|
||||
};
|
||||
const shaderCode = ImageShaderCode;
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId);
|
||||
|
||||
@@ -29,7 +29,6 @@ export function LinesRenderable(ctx: WebGLContext, id: number, values: LinesValu
|
||||
const schema = { ...GlobalUniformSchema, ...InternalSchema, ...LinesSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
uPickable: ValueCell.create(state.pickable ? 1 : 0)
|
||||
};
|
||||
const shaderCode = LinesShaderCode;
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId);
|
||||
|
||||
@@ -28,7 +28,6 @@ export function MeshRenderable(ctx: WebGLContext, id: number, values: MeshValues
|
||||
const schema = { ...GlobalUniformSchema, ...InternalSchema, ...MeshSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
uPickable: ValueCell.create(state.pickable ? 1 : 0)
|
||||
};
|
||||
const shaderCode = MeshShaderCode;
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId);
|
||||
|
||||
@@ -26,7 +26,6 @@ export function PointsRenderable(ctx: WebGLContext, id: number, values: PointsVa
|
||||
const schema = { ...GlobalUniformSchema, ...InternalSchema, ...PointsSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
uPickable: ValueCell.create(state.pickable ? 1 : 0)
|
||||
};
|
||||
const shaderCode = PointsShaderCode;
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'points', shaderCode, schema, { ...values, ...internalValues }, materialId);
|
||||
|
||||
@@ -187,7 +187,6 @@ export type GlobalUniformValues = Values<GlobalUniformSchema> // { [k in keyof G
|
||||
|
||||
export const InternalSchema = {
|
||||
uObjectId: UniformSpec('i'),
|
||||
uPickable: UniformSpec('i', true),
|
||||
} as const;
|
||||
export type InternalSchema = typeof InternalSchema
|
||||
export type InternalValues = { [k in keyof InternalSchema]: ValueCell<any> }
|
||||
|
||||
@@ -29,7 +29,6 @@ export function SpheresRenderable(ctx: WebGLContext, id: number, values: Spheres
|
||||
const schema = { ...GlobalUniformSchema, ...InternalSchema, ...SpheresSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
uPickable: ValueCell.create(state.pickable ? 1 : 0)
|
||||
};
|
||||
const shaderCode = SpheresShaderCode;
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId);
|
||||
|
||||
@@ -38,7 +38,6 @@ export function TextRenderable(ctx: WebGLContext, id: number, values: TextValues
|
||||
const schema = { ...GlobalUniformSchema, ...InternalSchema, ...TextSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
uPickable: ValueCell.create(state.pickable ? 1 : 0)
|
||||
};
|
||||
const shaderCode = TextShaderCode;
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId);
|
||||
|
||||
@@ -31,7 +31,6 @@ export function TextureMeshRenderable(ctx: WebGLContext, id: number, values: Tex
|
||||
const schema = { ...GlobalUniformSchema, ...InternalSchema, ...TextureMeshSchema };
|
||||
const internalValues: InternalValues = {
|
||||
uObjectId: ValueCell.create(id),
|
||||
uPickable: ValueCell.create(state.pickable ? 1 : 0)
|
||||
};
|
||||
const shaderCode = MeshShaderCode;
|
||||
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId);
|
||||
|
||||
@@ -20,6 +20,7 @@ export interface TextureImage<T extends Uint8Array | Float32Array> {
|
||||
readonly array: T
|
||||
readonly width: number
|
||||
readonly height: number
|
||||
readonly flipY?: boolean
|
||||
}
|
||||
|
||||
export interface TextureVolume<T extends Uint8Array | Float32Array> {
|
||||
|
||||
@@ -173,47 +173,53 @@ namespace Renderer {
|
||||
let globalUniformsNeedUpdate = true;
|
||||
|
||||
const renderObject = (r: Renderable<RenderableValues & BaseValues>, variant: GraphicsRenderVariant) => {
|
||||
if (!r.state.visible || (!r.state.pickable && variant[0] === 'p')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const program = r.getProgram(variant);
|
||||
if (r.state.visible) {
|
||||
if (state.currentProgramId !== program.id) {
|
||||
// console.log('new program')
|
||||
globalUniformsNeedUpdate = true;
|
||||
program.use();
|
||||
}
|
||||
if (state.currentProgramId !== program.id) {
|
||||
// console.log('new program')
|
||||
globalUniformsNeedUpdate = true;
|
||||
program.use();
|
||||
}
|
||||
|
||||
if (globalUniformsNeedUpdate) {
|
||||
// console.log('globalUniformsNeedUpdate')
|
||||
program.setUniforms(globalUniformList);
|
||||
globalUniformsNeedUpdate = false;
|
||||
}
|
||||
if (globalUniformsNeedUpdate) {
|
||||
// console.log('globalUniformsNeedUpdate')
|
||||
program.setUniforms(globalUniformList);
|
||||
globalUniformsNeedUpdate = false;
|
||||
}
|
||||
|
||||
if (r.values.dDoubleSided) {
|
||||
if (r.values.dDoubleSided.ref.value) {
|
||||
state.disable(gl.CULL_FACE);
|
||||
} else {
|
||||
state.enable(gl.CULL_FACE);
|
||||
}
|
||||
} else {
|
||||
// webgl default
|
||||
if (r.values.dDoubleSided) {
|
||||
if (r.values.dDoubleSided.ref.value) {
|
||||
state.disable(gl.CULL_FACE);
|
||||
}
|
||||
|
||||
if (r.values.dFlipSided) {
|
||||
if (r.values.dFlipSided.ref.value) {
|
||||
state.frontFace(gl.CW);
|
||||
state.cullFace(gl.FRONT);
|
||||
} else {
|
||||
state.frontFace(gl.CCW);
|
||||
state.cullFace(gl.BACK);
|
||||
}
|
||||
} else {
|
||||
// webgl default
|
||||
state.enable(gl.CULL_FACE);
|
||||
}
|
||||
} else {
|
||||
// webgl default
|
||||
state.disable(gl.CULL_FACE);
|
||||
}
|
||||
|
||||
if (r.values.dFlipSided) {
|
||||
if (r.values.dFlipSided.ref.value) {
|
||||
state.frontFace(gl.CW);
|
||||
state.cullFace(gl.FRONT);
|
||||
} else {
|
||||
state.frontFace(gl.CCW);
|
||||
state.cullFace(gl.BACK);
|
||||
}
|
||||
|
||||
r.render(variant);
|
||||
} else {
|
||||
// webgl default
|
||||
state.frontFace(gl.CCW);
|
||||
state.cullFace(gl.BACK);
|
||||
}
|
||||
|
||||
if (variant === 'color') {
|
||||
state.depthMask(r.state.writeDepth);
|
||||
}
|
||||
|
||||
r.render(variant);
|
||||
};
|
||||
|
||||
const render = (scene: Scene, camera: Camera, variant: GraphicsRenderVariant, clear: boolean, transparentBackground: boolean) => {
|
||||
@@ -245,11 +251,11 @@ namespace Renderer {
|
||||
|
||||
state.disable(gl.SCISSOR_TEST);
|
||||
state.disable(gl.BLEND);
|
||||
state.depthMask(true);
|
||||
state.colorMask(true, true, true, true);
|
||||
state.enable(gl.DEPTH_TEST);
|
||||
|
||||
if (clear) {
|
||||
state.depthMask(true);
|
||||
if (variant === 'color') {
|
||||
state.clearColor(bgColor[0], bgColor[1], bgColor[2], transparentBackground ? 0 : 1);
|
||||
} else {
|
||||
@@ -268,10 +274,11 @@ namespace Renderer {
|
||||
state.enable(gl.BLEND);
|
||||
for (let i = 0, il = renderables.length; i < il; ++i) {
|
||||
const r = renderables[i];
|
||||
if (!r.state.opaque) {
|
||||
state.depthMask(false);
|
||||
renderObject(r, variant);
|
||||
}
|
||||
if (!r.state.opaque && r.state.writeDepth) renderObject(r, variant);
|
||||
}
|
||||
for (let i = 0, il = renderables.length; i < il; ++i) {
|
||||
const r = renderables[i];
|
||||
if (!r.state.opaque && !r.state.writeDepth) renderObject(r, variant);
|
||||
}
|
||||
} else { // picking & depth
|
||||
for (let i = 0, il = renderables.length; i < il; ++i) {
|
||||
|
||||
@@ -50,9 +50,11 @@ function renderableSort(a: Renderable<RenderableValues & BaseValues>, b: Rendera
|
||||
const materialIdB = b.materialId;
|
||||
|
||||
if (drawProgramIdA !== drawProgramIdB) {
|
||||
return drawProgramIdA - drawProgramIdB; // sort by program id to minimize gl state changes
|
||||
// sort by program id to minimize gl state changes
|
||||
return drawProgramIdA - drawProgramIdB;
|
||||
} else if (materialIdA !== materialIdB) {
|
||||
return materialIdA - materialIdB; // sort by material id to minimize gl state changes
|
||||
// sort by material id to minimize gl state changes
|
||||
return materialIdA - materialIdB;
|
||||
} else {
|
||||
return a.id - b.id;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
export default `
|
||||
float depth = length(vViewPosition);
|
||||
float fogFactor = smoothstep(uFogNear, uFogFar, depth);
|
||||
float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a;
|
||||
if (uTransparentBackground == 0) {
|
||||
gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor, fogFactor);
|
||||
if (gl_FragColor.a < 1.0)
|
||||
gl_FragColor.a = fogAlpha;
|
||||
} else {
|
||||
float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a;
|
||||
gl_FragColor.a = fogAlpha;
|
||||
|
||||
@@ -34,7 +34,7 @@ export default `
|
||||
if (ta < 0.99 && (ta < 0.01 || ta < at)) discard;
|
||||
#endif
|
||||
#elif defined(dRenderVariant_pick)
|
||||
vec4 material = uPickable == 1 ? vColor : vec4(0.0, 0.0, 0.0, 1.0); // set to empty picking id
|
||||
vec4 material = vColor;
|
||||
#elif defined(dRenderVariant_depth)
|
||||
#ifdef enabledFragDepth
|
||||
vec4 material = packDepthToRGBA(gl_FragDepthEXT);
|
||||
|
||||
@@ -21,7 +21,6 @@ uniform vec3 uFogColor;
|
||||
|
||||
uniform float uAlpha;
|
||||
uniform float uPickingAlphaThreshold;
|
||||
uniform int uPickable;
|
||||
uniform int uTransparentBackground;
|
||||
|
||||
uniform float uInteriorDarkening;
|
||||
|
||||
@@ -28,7 +28,6 @@ uniform sampler2D tMarker;
|
||||
|
||||
uniform float uAlpha;
|
||||
uniform float uPickingAlphaThreshold;
|
||||
uniform int uPickable;
|
||||
|
||||
#if defined(dGridTexType_2d)
|
||||
precision highp sampler2D;
|
||||
@@ -117,8 +116,6 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) {
|
||||
#if defined(dRenderVariant_pick)
|
||||
if (uAlpha < uPickingAlphaThreshold)
|
||||
discard; // ignore so the element below can be picked
|
||||
if (uPickable == 0)
|
||||
return vec4(0.0, 0.0, 0.0, 1.0); // set to empty picking id
|
||||
#endif
|
||||
|
||||
#if defined(dRenderVariant_pickObject)
|
||||
|
||||
@@ -35,20 +35,20 @@ varying float vInstance;
|
||||
const float C = 0.333;
|
||||
#endif
|
||||
|
||||
float cubicFilter( float x ){
|
||||
float cubicFilter(float x){
|
||||
float f = x;
|
||||
if( f < 0.0 ){
|
||||
if (f < 0.0) {
|
||||
f = -f;
|
||||
}
|
||||
if( f < 1.0 ){
|
||||
return ( ( 12.0 - 9.0 * B - 6.0 * C ) * ( f * f * f ) +
|
||||
( -18.0 + 12.0 * B + 6.0 *C ) * ( f * f ) +
|
||||
( 6.0 - 2.0 * B ) ) / 6.0;
|
||||
}else if( f >= 1.0 && f < 2.0 ){
|
||||
return ( ( -B - 6.0 * C ) * ( f * f * f )
|
||||
+ ( 6.0 * B + 30.0 * C ) * ( f *f ) +
|
||||
( - ( 12.0 * B ) - 48.0 * C ) * f +
|
||||
8.0 * B + 24.0 * C ) / 6.0;
|
||||
if (f < 1.0) {
|
||||
return ((12.0 - 9.0 * B - 6.0 * C) * (f * f * f) +
|
||||
(-18.0 + 12.0 * B + 6.0 * C) * (f * f) +
|
||||
(6.0 - 2.0 * B)) / 6.0;
|
||||
}else if (f >= 1.0 && f < 2.0){
|
||||
return ((-B - 6.0 * C) * ( f * f * f)
|
||||
+ (6.0 * B + 30.0 * C) * (f * f) +
|
||||
(-(12.0 * B) - 48.0 * C) * f +
|
||||
8.0 * B + 24.0 * C) / 6.0;
|
||||
}else{
|
||||
return 0.0;
|
||||
}
|
||||
@@ -92,25 +92,23 @@ void main() {
|
||||
#else
|
||||
vec4 imageData = texture2D(tImageTex, vUv);
|
||||
#endif
|
||||
imageData.a = clamp(imageData.a, 0.0, 1.0);
|
||||
if (imageData.a > 0.9) imageData.a = 1.0;
|
||||
|
||||
#if defined(dRenderVariant_pick)
|
||||
if (imageData.a < 0.3)
|
||||
discard;
|
||||
|
||||
if (uPickable == 1) {
|
||||
#if defined(dRenderVariant_pickObject)
|
||||
gl_FragColor = vec4(encodeFloatRGB(float(uObjectId)), 1.0);
|
||||
#elif defined(dRenderVariant_pickInstance)
|
||||
gl_FragColor = vec4(encodeFloatRGB(vInstance), 1.0);
|
||||
#elif defined(dRenderVariant_pickGroup)
|
||||
float group = texture2D(tGroupTex, vUv).r;
|
||||
gl_FragColor = vec4(encodeFloatRGB(group), 1.0);
|
||||
#endif
|
||||
} else {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); // set to empty picking id
|
||||
}
|
||||
#if defined(dRenderVariant_pickObject)
|
||||
gl_FragColor = vec4(encodeFloatRGB(float(uObjectId)), 1.0);
|
||||
#elif defined(dRenderVariant_pickInstance)
|
||||
gl_FragColor = vec4(encodeFloatRGB(vInstance), 1.0);
|
||||
#elif defined(dRenderVariant_pickGroup)
|
||||
float group = texture2D(tGroupTex, vUv).r;
|
||||
gl_FragColor = vec4(encodeFloatRGB(group), 1.0);
|
||||
#endif
|
||||
#elif defined(dRenderVariant_depth)
|
||||
if (imageData.a < 0.01)
|
||||
if (imageData.a < 0.05)
|
||||
discard;
|
||||
|
||||
#ifdef enabledFragDepth
|
||||
@@ -119,7 +117,7 @@ void main() {
|
||||
gl_FragColor = packDepthToRGBA(gl_FragCoord.z);
|
||||
#endif
|
||||
#elif defined(dRenderVariant_color)
|
||||
if (imageData.a < 0.01)
|
||||
if (imageData.a < 0.05)
|
||||
discard;
|
||||
|
||||
gl_FragColor = imageData;
|
||||
|
||||
@@ -118,6 +118,14 @@ export function getAttachment(gl: GLRenderingContext, extensions: WebGLExtension
|
||||
throw new Error('unknown texture attachment');
|
||||
}
|
||||
|
||||
function isTexture2d(x: TextureImage<any> | TextureVolume<any>, target: number, gl: GLRenderingContext): x is TextureImage<any> {
|
||||
return target === gl.TEXTURE_2D;
|
||||
}
|
||||
|
||||
function isTexture3d(x: TextureImage<any> | TextureVolume<any>, target: number, gl: WebGL2RenderingContext): x is TextureImage<any> {
|
||||
return target === gl.TEXTURE_3D;
|
||||
}
|
||||
|
||||
export interface Texture {
|
||||
readonly id: number
|
||||
readonly target: number
|
||||
@@ -214,14 +222,13 @@ export function createTexture(gl: GLRenderingContext, extensions: WebGLExtension
|
||||
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
|
||||
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
|
||||
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);
|
||||
if (target === gl.TEXTURE_2D) {
|
||||
const { array, width: _width, height: _height } = data as TextureImage<any>;
|
||||
width = _width, height = _height;
|
||||
gl.texImage2D(target, 0, internalFormat, width, height, 0, format, type, array);
|
||||
} else if (isWebGL2(gl) && target === gl.TEXTURE_3D) {
|
||||
const { array, width: _width, height: _height, depth: _depth } = data as TextureVolume<any>;
|
||||
width = _width, height = _height, depth = _depth;
|
||||
gl.texImage3D(target, 0, internalFormat, width, height, depth, 0, format, type, array);
|
||||
if (isTexture2d(data, target, gl)) {
|
||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, !!data.flipY);
|
||||
width = data.width, height = data.height;
|
||||
gl.texImage2D(target, 0, internalFormat, width, height, 0, format, type, data.array);
|
||||
} else if (isWebGL2(gl) && isTexture3d(data, target, gl)) {
|
||||
width = data.width, height = data.height, depth = data.depth;
|
||||
gl.texImage3D(target, 0, internalFormat, width, height, depth, 0, format, type, data.array);
|
||||
} else {
|
||||
throw new Error('unknown texture target');
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { SimpleBuffer } from './simple-buffer';
|
||||
const fs = typeof document === 'undefined' ? require('fs') as typeof import('fs') : void 0;
|
||||
|
||||
export interface FileHandle {
|
||||
name: string
|
||||
/**
|
||||
* Asynchronously reads data, returning buffer and number of bytes read
|
||||
*
|
||||
@@ -44,8 +45,9 @@ export interface FileHandle {
|
||||
}
|
||||
|
||||
export namespace FileHandle {
|
||||
export function fromBuffer(buffer: SimpleBuffer): FileHandle {
|
||||
export function fromBuffer(buffer: SimpleBuffer, name: string): FileHandle {
|
||||
return {
|
||||
name,
|
||||
readBuffer: (position: number, sizeOrBuffer: SimpleBuffer | number, size?: number, byteOffset?: number) => {
|
||||
let bytesRead: number;
|
||||
let outBuffer: SimpleBuffer;
|
||||
@@ -82,9 +84,10 @@ export namespace FileHandle {
|
||||
};
|
||||
}
|
||||
|
||||
export function fromDescriptor(file: number): FileHandle {
|
||||
export function fromDescriptor(file: number, name: string): FileHandle {
|
||||
if (fs === undefined) throw new Error('fs module not available');
|
||||
return {
|
||||
name,
|
||||
readBuffer: (position: number, sizeOrBuffer: SimpleBuffer | number, length?: number, byteOffset?: number) => {
|
||||
return new Promise((res, rej) => {
|
||||
let outBuffer: SimpleBuffer;
|
||||
|
||||
@@ -31,7 +31,7 @@ function createCcp4Data() {
|
||||
describe('ccp4 reader', () => {
|
||||
it('basic', async () => {
|
||||
const data = createCcp4Data();
|
||||
const parsed = await CCP4.parse(data).run();
|
||||
const parsed = await CCP4.parse(data, 'test.ccp4').run();
|
||||
|
||||
if (parsed.isError) {
|
||||
throw new Error(parsed.message);
|
||||
|
||||
@@ -8,10 +8,14 @@ import { parseFloat as fastParseFloat, parseInt as fastParseInt, getNumberType,
|
||||
|
||||
describe('common', () => {
|
||||
it('number-parser fastParseFloat', () => {
|
||||
// ignore suffix numbers in parentheses
|
||||
expect(fastParseFloat('11.0829(23)', 0, 11)).toBe(11.0829);
|
||||
// scientific with no space between consecutive values
|
||||
expect(fastParseFloat('-5.1E-01-6.1E-01', 0, 11)).toBe(-0.51);
|
||||
});
|
||||
|
||||
it('number-parser fastParseInt', () => {
|
||||
// ignore suffix numbers in parentheses
|
||||
expect(fastParseInt('11(23)', 0, 11)).toBe(11);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import Mol2 from '../mol2/parser';
|
||||
import { parseMol2 } from '../mol2/parser';
|
||||
|
||||
const Mol2String = `@<TRIPOS>MOLECULE
|
||||
5816
|
||||
@@ -246,7 +246,7 @@ GASTEIGER
|
||||
|
||||
describe('mol2 reader', () => {
|
||||
it('basic', async () => {
|
||||
const parsed = await Mol2(Mol2String).run();
|
||||
const parsed = await parseMol2(Mol2String, '').run();
|
||||
if (parsed.isError) {
|
||||
throw new Error(parsed.message);
|
||||
}
|
||||
@@ -297,7 +297,7 @@ describe('mol2 reader', () => {
|
||||
});
|
||||
|
||||
it('multiblocks', async () => {
|
||||
const parsed = await Mol2(Mol2StringMultiBlocks).run();
|
||||
const parsed = await parseMol2(Mol2StringMultiBlocks, '').run();
|
||||
if (parsed.isError) {
|
||||
throw new Error(parsed.message);
|
||||
}
|
||||
@@ -348,7 +348,7 @@ describe('mol2 reader', () => {
|
||||
});
|
||||
|
||||
it('minimal', async () => {
|
||||
const parsed = await Mol2(Mol2StringMinimal).run();
|
||||
const parsed = await parseMol2(Mol2StringMinimal, '').run();
|
||||
if (parsed.isError) {
|
||||
throw new Error(parsed.message);
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ async function parseInternal(file: FileHandle, size: number, ctx: RuntimeContext
|
||||
const buffer = createTypedArrayBufferContext(count, valueType);
|
||||
readCcp4Slices(header, buffer, file, offset, byteCount, littleEndian);
|
||||
|
||||
const result: Ccp4File = { header, values: buffer.values };
|
||||
const result: Ccp4File = { header, values: buffer.values, name: file.name };
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -174,6 +174,6 @@ export function parseFile(file: FileHandle, size: number) {
|
||||
});
|
||||
}
|
||||
|
||||
export function parse(buffer: Uint8Array) {
|
||||
return parseFile(FileHandle.fromBuffer(SimpleBuffer.fromUint8Array(buffer)), buffer.length);
|
||||
export function parse(buffer: Uint8Array, name: string) {
|
||||
return parseFile(FileHandle.fromBuffer(SimpleBuffer.fromUint8Array(buffer), name), buffer.length);
|
||||
}
|
||||
@@ -114,6 +114,7 @@ export interface Ccp4Header {
|
||||
* CCP4 format does not use the ORIGIN header records (words 50-52)
|
||||
*/
|
||||
export interface Ccp4File {
|
||||
name: string
|
||||
header: Ccp4Header
|
||||
values: Float32Array | Int16Array | Int8Array | Uint16Array
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import { parseFloat as fastParseFloat } from '../common/text/number-parser';
|
||||
// https://h5cube-spec.readthedocs.io/en/latest/cubeformat.html
|
||||
|
||||
export interface CubeFile {
|
||||
name: string,
|
||||
header: CubeFile.Header,
|
||||
atoms: CubeFile.Atoms,
|
||||
values: Float64Array
|
||||
@@ -24,6 +25,7 @@ export interface CubeFile {
|
||||
|
||||
export namespace CubeFile {
|
||||
export interface Header {
|
||||
orbitals: boolean,
|
||||
comment1: string,
|
||||
comment2: string,
|
||||
atomCount: number,
|
||||
@@ -79,8 +81,7 @@ function readHeader(tokenizer: Tokenizer) {
|
||||
for (let i = 0, _i = +counts[0]; i < _i; i++) dataSetIds.push(+counts[i + 1]);
|
||||
}
|
||||
|
||||
const header: CubeFile.Header = { comment1, comment2, atomCount, origin, dim: Vec3.create(NVX, NVY, NVZ), basisX, basisY, basisZ, dataSetIds };
|
||||
|
||||
const header: CubeFile.Header = { orbitals: rawAtomCount < 0, comment1, comment2, atomCount, origin, dim: Vec3.create(NVX, NVY, NVZ), basisX, basisY, basisZ, dataSetIds };
|
||||
return { header, atoms };
|
||||
}
|
||||
|
||||
@@ -129,12 +130,12 @@ function readValues(ctx: RuntimeContext, tokenizer: Tokenizer, header: CubeFile.
|
||||
}, (ctx, _, i) => ctx.update({ current: Math.min(i, N), max: N }));
|
||||
}
|
||||
|
||||
export function parseCube(data: string) {
|
||||
export function parseCube(data: string, name: string) {
|
||||
return Task.create<Result<CubeFile>>('Parse Cube', async taskCtx => {
|
||||
await taskCtx.update('Reading header...');
|
||||
const tokenizer = Tokenizer(data);
|
||||
const { header, atoms } = readHeader(tokenizer);
|
||||
const values = await readValues(taskCtx, tokenizer, header);
|
||||
return Result.success({ header, atoms, values });
|
||||
return Result.success({ header, atoms, values, name });
|
||||
});
|
||||
}
|
||||
@@ -134,7 +134,7 @@ async function parseInternal(file: FileHandle, size: number, ctx: RuntimeContext
|
||||
const values = new Float32Array(valueCount);
|
||||
await parseDsn6Values(header, buffer, values, littleEndian);
|
||||
|
||||
const result: Dsn6File = { header, values };
|
||||
const result: Dsn6File = { header, values, name: file.name };
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -148,6 +148,6 @@ export function parseFile(file: FileHandle, size: number) {
|
||||
});
|
||||
}
|
||||
|
||||
export function parse(buffer: Uint8Array) {
|
||||
return parseFile(FileHandle.fromBuffer(SimpleBuffer.fromUint8Array(buffer)), buffer.length);
|
||||
export function parse(buffer: Uint8Array, name: string) {
|
||||
return parseFile(FileHandle.fromBuffer(SimpleBuffer.fromUint8Array(buffer), name), buffer.length);
|
||||
}
|
||||
@@ -39,6 +39,7 @@ export interface Dsn6Header {
|
||||
* BRIX http://svn.cgl.ucsf.edu/svn/chimera/trunk/libs/VolumeData/dsn6/brix-1.html
|
||||
*/
|
||||
export interface Dsn6File {
|
||||
name: string
|
||||
header: Dsn6Header
|
||||
values: Float32Array
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import { utf8Read } from '../../common/utf8';
|
||||
// http://apbs-pdb2pqr.readthedocs.io/en/latest/formats/opendx.html
|
||||
|
||||
export interface DxFile {
|
||||
name: string,
|
||||
header: DxFile.Header,
|
||||
values: Float64Array
|
||||
}
|
||||
@@ -88,16 +89,16 @@ function readValuesText(ctx: RuntimeContext, tokenizer: Tokenizer, header: DxFil
|
||||
}, (ctx, _, i) => ctx.update({ current: Math.min(i, N), max: N }));
|
||||
}
|
||||
|
||||
async function parseText(taskCtx: RuntimeContext, data: string) {
|
||||
async function parseText(taskCtx: RuntimeContext, data: string, name: string) {
|
||||
await taskCtx.update('Reading header...');
|
||||
const tokenizer = Tokenizer(data as string);
|
||||
const { header } = readHeader(tokenizer);
|
||||
await taskCtx.update('Reading values...');
|
||||
const values = await readValuesText(taskCtx, tokenizer, header);
|
||||
return Result.success({ header, values });
|
||||
return Result.success({ header, values, name });
|
||||
}
|
||||
|
||||
async function parseBinary(taskCtx: RuntimeContext, data: Uint8Array) {
|
||||
async function parseBinary(taskCtx: RuntimeContext, data: Uint8Array, name: string) {
|
||||
await taskCtx.update('Reading header...');
|
||||
|
||||
const headerString = utf8Read(data, 0, 1000);
|
||||
@@ -117,12 +118,12 @@ async function parseBinary(taskCtx: RuntimeContext, data: Uint8Array) {
|
||||
|
||||
// TODO: why doesnt this work? throw "attempting to construct out-of-bounds TypedArray"
|
||||
// const values = new Float64Array(data.buffer, data.byteOffset + headerByteCount, header.dim[0] * header.dim[1] * header.dim[2]);
|
||||
return Result.success({ header, values });
|
||||
return Result.success({ header, values, name });
|
||||
}
|
||||
|
||||
export function parseDx(data: string | Uint8Array) {
|
||||
export function parseDx(data: string | Uint8Array, name: string) {
|
||||
return Task.create<Result<DxFile>>('Parse Cube', taskCtx => {
|
||||
if (typeof data === 'string') return parseText(taskCtx, data);
|
||||
return parseBinary(taskCtx, data);
|
||||
if (typeof data === 'string') return parseText(taskCtx, data, name);
|
||||
return parseBinary(taskCtx, data, name);
|
||||
});
|
||||
}
|
||||
@@ -54,7 +54,7 @@ const reWhitespace = /\s+/g;
|
||||
function handleMolecule(state: State) {
|
||||
const { tokenizer, molecule } = state;
|
||||
|
||||
while (getTokenString(tokenizer) !== '@<TRIPOS>MOLECULE') {
|
||||
while (getTokenString(tokenizer) !== '@<TRIPOS>MOLECULE' && tokenizer.position < tokenizer.data.length) {
|
||||
markLine(tokenizer);
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ async function handleAtoms(state: State): Promise<Schema.Mol2Atoms> {
|
||||
let hasStatus_bit = false;
|
||||
|
||||
// skip empty lines and '@<TRIPOS>ATOM'
|
||||
while (getTokenString(tokenizer) !== '@<TRIPOS>ATOM') {
|
||||
while (getTokenString(tokenizer) !== '@<TRIPOS>ATOM' && tokenizer.position < tokenizer.data.length) {
|
||||
markLine(tokenizer);
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ async function handleBonds(state: State): Promise<Schema.Mol2Bonds> {
|
||||
const { tokenizer, molecule } = state;
|
||||
let hasStatus_bit = false;
|
||||
|
||||
while (getTokenString(tokenizer) !== '@<TRIPOS>BOND') {
|
||||
while (getTokenString(tokenizer) !== '@<TRIPOS>BOND' && tokenizer.position < tokenizer.data.length) {
|
||||
markLine(tokenizer);
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ async function handleBonds(state: State): Promise<Schema.Mol2Bonds> {
|
||||
return ret;
|
||||
}
|
||||
|
||||
async function parseInternal(data: string, ctx: RuntimeContext): Promise<Result<Schema.Mol2File>> {
|
||||
async function parseInternal(ctx: RuntimeContext, data: string, name: string): Promise<Result<Schema.Mol2File>> {
|
||||
const tokenizer = Tokenizer(data);
|
||||
|
||||
ctx.update({ message: 'Parsing...', current: 0, max: data.length });
|
||||
@@ -335,16 +335,15 @@ async function parseInternal(data: string, ctx: RuntimeContext): Promise<Result<
|
||||
const atoms = await handleAtoms(state);
|
||||
const bonds = await handleBonds(state);
|
||||
structures.push({ molecule: state.molecule, atoms, bonds });
|
||||
skipWhitespace(tokenizer);
|
||||
}
|
||||
|
||||
const result: Schema.Mol2File = { structures };
|
||||
const result: Schema.Mol2File = { name, structures };
|
||||
return Result.success(result);
|
||||
}
|
||||
|
||||
export function parse(data: string) {
|
||||
export function parseMol2(data: string, name: string) {
|
||||
return Task.create<Result<Schema.Mol2File>>('Parse MOL2', async ctx => {
|
||||
return await parseInternal(data, ctx);
|
||||
return await parseInternal(ctx, data, name);
|
||||
});
|
||||
}
|
||||
|
||||
export default parse;
|
||||
}
|
||||
1
src/mol-io/reader/mol2/schema.d.ts
vendored
1
src/mol-io/reader/mol2/schema.d.ts
vendored
@@ -63,5 +63,6 @@ export interface Mol2Structure {
|
||||
}
|
||||
|
||||
export interface Mol2File {
|
||||
name: string
|
||||
structures: Mol2Structure[]
|
||||
}
|
||||
@@ -263,4 +263,59 @@ describe('tensor', () => {
|
||||
|
||||
expect(data).toEqual(exp);
|
||||
});
|
||||
|
||||
it('indexing', () => {
|
||||
function permutations<T>(inputArr: T[]): T[][] {
|
||||
let result: T[][] = [];
|
||||
function permute(arr: any, m: any = []) {
|
||||
if (arr.length === 0) {
|
||||
result.push(m);
|
||||
} else {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let curr = arr.slice();
|
||||
let next = curr.splice(i, 1);
|
||||
permute(curr.slice(), m.concat(next));
|
||||
}
|
||||
}
|
||||
}
|
||||
permute(inputArr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
for (let dim = 1; dim <= 5; dim++) {
|
||||
const axes = [], dims: number[] = [];
|
||||
const u: number[] = [], v: number[] = [];
|
||||
|
||||
for (let i = 0; i < dim; i++) {
|
||||
axes.push(i);
|
||||
dims.push(3);
|
||||
u.push(0);
|
||||
v.push(0);
|
||||
}
|
||||
|
||||
const forEachDim = (space: T.Space, d: number): boolean => {
|
||||
if (d === dim) {
|
||||
const o = space.dataOffset(...u);
|
||||
space.getCoords(o, v);
|
||||
|
||||
for (let e = 0; e < dims.length; e++) {
|
||||
expect(u[e]).toEqual(v[e]);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < dims[d]; i++) {
|
||||
u[d] = i;
|
||||
if (!forEachDim(space, d + 1)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
for (const ao of permutations(axes)) {
|
||||
const space = T.Space(dims, ao);
|
||||
if (!forEachDim(space, 0)) break;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author David Sehnal <david.sehnal@gmail.com>
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { Mat4, Vec3, Vec4, Mat3 } from './3d';
|
||||
@@ -21,6 +22,8 @@ export namespace Tensor {
|
||||
get(data: Tensor.Data, ...coords: number[]): number
|
||||
set(data: Tensor.Data, ...coordsAndValue: number[]): number
|
||||
add(data: Tensor.Data, ...coordsAndValue: number[]): number
|
||||
dataOffset(...coords: number[]): number,
|
||||
getCoords(dataOffset: number, coords: { [i: number]: number }): number[]
|
||||
}
|
||||
|
||||
interface Layout {
|
||||
@@ -46,8 +49,8 @@ export namespace Tensor {
|
||||
|
||||
export function Space(dimensions: number[], axisOrderSlowToFast: number[], ctor?: ArrayCtor): Space {
|
||||
const layout = Layout(dimensions, axisOrderSlowToFast, ctor);
|
||||
const { get, set, add } = accessors(layout);
|
||||
return { rank: dimensions.length, dimensions, axisOrderSlowToFast, create: creator(layout), get, set, add };
|
||||
const { get, set, add, dataOffset, getCoords } = accessors(layout);
|
||||
return { rank: dimensions.length, dimensions, axisOrderSlowToFast, create: creator(layout), get, set, add, dataOffset, getCoords };
|
||||
}
|
||||
|
||||
export function Data1(values: ArrayLike<number>): Data { return values as Data; }
|
||||
@@ -95,13 +98,15 @@ export namespace Tensor {
|
||||
return true;
|
||||
}
|
||||
|
||||
function accessors(layout: Layout): { get: Space['get'], set: Space['set'], add: Space['add'] } {
|
||||
function accessors(layout: Layout): { get: Space['get'], set: Space['set'], add: Space['add'], dataOffset: Space['dataOffset'], getCoords: Space['getCoords'] } {
|
||||
const { dimensions, axisOrderFastToSlow: ao } = layout;
|
||||
switch (dimensions.length) {
|
||||
case 1: return {
|
||||
get: (t, d) => t[d],
|
||||
set: (t, d, x) => t[d] = x,
|
||||
add: (t, d, x) => t[d] += x
|
||||
add: (t, d, x) => t[d] += x,
|
||||
dataOffset: (d) => d,
|
||||
getCoords: (o, c) => { c[0] = o; return c as number[]; }
|
||||
};
|
||||
case 2: {
|
||||
// column major
|
||||
@@ -110,7 +115,9 @@ export namespace Tensor {
|
||||
return {
|
||||
get: (t, i, j) => t[j * rows + i],
|
||||
set: (t, i, j, x) => t[j * rows + i] = x,
|
||||
add: (t, i, j, x) => t[j * rows + i] += x
|
||||
add: (t, i, j, x) => t[j * rows + i] += x,
|
||||
dataOffset: (i, j) => j * rows + i,
|
||||
getCoords: (o, c) => { c[0] = o % rows; c[1] = Math.floor(o / rows) ; return c as number[]; }
|
||||
};
|
||||
}
|
||||
if (ao[0] === 1 && ao[1] === 0) {
|
||||
@@ -118,7 +125,9 @@ export namespace Tensor {
|
||||
return {
|
||||
get: (t, i, j) => t[i * cols + j],
|
||||
set: (t, i, j, x) => t[i * cols + j] = x,
|
||||
add: (t, i, j, x) => t[i * cols + j] += x
|
||||
add: (t, i, j, x) => t[i * cols + j] += x,
|
||||
dataOffset: (i, j) => i * cols + j,
|
||||
getCoords: (o, c) => { c[0] = Math.floor(o / cols); c[1] = o % cols; return c as number[]; }
|
||||
};
|
||||
}
|
||||
throw new Error('bad axis order');
|
||||
@@ -129,7 +138,15 @@ export namespace Tensor {
|
||||
return {
|
||||
get: (t, i, j, k) => t[i + j * u + k * uv],
|
||||
set: (t, i, j, k, x ) => t[i + j * u + k * uv] = x,
|
||||
add: (t, i, j, k, x ) => t[i + j * u + k * uv] += x
|
||||
add: (t, i, j, k, x ) => t[i + j * u + k * uv] += x,
|
||||
dataOffset: (i, j, k) => i + j * u + k * uv,
|
||||
getCoords: (o, c) => {
|
||||
const p = Math.floor(o / u);
|
||||
c[0] = o % u;
|
||||
c[1] = p % v;
|
||||
c[2] = Math.floor(p / v);
|
||||
return c as number[];
|
||||
}
|
||||
};
|
||||
}
|
||||
if (ao[0] === 0 && ao[1] === 2 && ao[2] === 1) { // 021 ikj
|
||||
@@ -137,7 +154,15 @@ export namespace Tensor {
|
||||
return {
|
||||
get: (t, i, j, k) => t[i + k * u + j * uv],
|
||||
set: (t, i, j, k, x ) => t[i + k * u + j * uv] = x,
|
||||
add: (t, i, j, k, x ) => t[i + k * u + j * uv] += x
|
||||
add: (t, i, j, k, x ) => t[i + k * u + j * uv] += x,
|
||||
dataOffset: (i, j, k) => i + k * u + j * uv,
|
||||
getCoords: (o, c) => {
|
||||
const p = Math.floor(o / u);
|
||||
c[0] = o % u;
|
||||
c[1] = Math.floor(p / v);
|
||||
c[2] = p % v;
|
||||
return c as number[];
|
||||
}
|
||||
};
|
||||
}
|
||||
if (ao[0] === 1 && ao[1] === 0 && ao[2] === 2) { // 102 jik
|
||||
@@ -145,7 +170,15 @@ export namespace Tensor {
|
||||
return {
|
||||
get: (t, i, j, k) => t[j + i * u + k * uv],
|
||||
set: (t, i, j, k, x ) => t[j + i * u + k * uv] = x,
|
||||
add: (t, i, j, k, x ) => t[j + i * u + k * uv] += x
|
||||
add: (t, i, j, k, x ) => t[j + i * u + k * uv] += x,
|
||||
dataOffset: (i, j, k) => j + i * u + k * uv,
|
||||
getCoords: (o, c) => {
|
||||
const p = Math.floor(o / u);
|
||||
c[0] = p % v;
|
||||
c[1] = o % u;
|
||||
c[2] = Math.floor(p / v);
|
||||
return c as number[];
|
||||
}
|
||||
};
|
||||
}
|
||||
if (ao[0] === 1 && ao[1] === 2 && ao[2] === 0) { // 120 jki
|
||||
@@ -153,7 +186,15 @@ export namespace Tensor {
|
||||
return {
|
||||
get: (t, i, j, k) => t[j + k * u + i * uv],
|
||||
set: (t, i, j, k, x ) => t[j + k * u + i * uv] = x,
|
||||
add: (t, i, j, k, x ) => t[j + k * u + i * uv] += x
|
||||
add: (t, i, j, k, x ) => t[j + k * u + i * uv] += x,
|
||||
dataOffset: (i, j, k) => j + k * u + i * uv,
|
||||
getCoords: (o, c) => {
|
||||
const p = Math.floor(o / u);
|
||||
c[0] = Math.floor(p / v);
|
||||
c[1] = o % u;
|
||||
c[2] = p % v;
|
||||
return c as number[];
|
||||
}
|
||||
};
|
||||
}
|
||||
if (ao[0] === 2 && ao[1] === 0 && ao[2] === 1) { // 201 kij
|
||||
@@ -161,7 +202,15 @@ export namespace Tensor {
|
||||
return {
|
||||
get: (t, i, j, k) => t[k + i * u + j * uv],
|
||||
set: (t, i, j, k, x ) => t[k + i * u + j * uv] = x,
|
||||
add: (t, i, j, k, x ) => t[k + i * u + j * uv] += x
|
||||
add: (t, i, j, k, x ) => t[k + i * u + j * uv] += x,
|
||||
dataOffset: (i, j, k) => k + i * u + j * uv,
|
||||
getCoords: (o, c) => {
|
||||
const p = Math.floor(o / u);
|
||||
c[0] = p % v;
|
||||
c[1] = Math.floor(p / v);
|
||||
c[2] = o % u;
|
||||
return c as number[];
|
||||
}
|
||||
};
|
||||
}
|
||||
if (ao[0] === 2 && ao[1] === 1 && ao[2] === 0) { // 210 kji
|
||||
@@ -169,7 +218,15 @@ export namespace Tensor {
|
||||
return {
|
||||
get: (t, i, j, k) => t[k + j * u + i * uv],
|
||||
set: (t, i, j, k, x ) => t[k + j * u + i * uv] = x,
|
||||
add: (t, i, j, k, x ) => t[k + j * u + i * uv] += x
|
||||
add: (t, i, j, k, x ) => t[k + j * u + i * uv] += x,
|
||||
dataOffset: (i, j, k) => k + j * u + i * uv,
|
||||
getCoords: (o, c) => {
|
||||
const p = Math.floor(o / u);
|
||||
c[0] = Math.floor(p / v);
|
||||
c[1] = p % v;
|
||||
c[2] = o % u;
|
||||
return c as number[];
|
||||
}
|
||||
};
|
||||
}
|
||||
throw new Error('bad axis order');
|
||||
@@ -177,7 +234,9 @@ export namespace Tensor {
|
||||
default: return {
|
||||
get: (t, ...c) => t[dataOffset(layout, c)],
|
||||
set: (t, ...c) => t[dataOffset(layout, c)] = c[c.length - 1],
|
||||
add: (t, ...c) => t[dataOffset(layout, c)] += c[c.length - 1]
|
||||
add: (t, ...c) => t[dataOffset(layout, c)] += c[c.length - 1],
|
||||
dataOffset: (...c) => dataOffset(layout, c),
|
||||
getCoords: (o, c) => getCoords(layout, o, c as number[]),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -199,6 +258,21 @@ export namespace Tensor {
|
||||
return o;
|
||||
}
|
||||
|
||||
function getCoords(layout: Layout, o: number, coords: number[]) {
|
||||
const { dimensions: dim, axisOrderFastToSlow: ao } = layout;
|
||||
const d = dim.length;
|
||||
|
||||
let c = o;
|
||||
for (let i = 0; i < d; i++) {
|
||||
const d = dim[ao[i]];
|
||||
coords[ao[i]] = c % d;
|
||||
c = Math.floor(c / d);
|
||||
}
|
||||
coords[ao[d + 1]] = c;
|
||||
|
||||
return coords;
|
||||
}
|
||||
|
||||
// Convers "slow to fast" axis order to "fast to slow" and vice versa.
|
||||
export function invertAxisOrder(v: number[]) {
|
||||
const ret: number[] = [];
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { Model } from '../../mol-model/structure/model';
|
||||
import { Task } from '../../mol-task';
|
||||
import { ModelFormat } from './format';
|
||||
import { ModelFormat } from '../format';
|
||||
import { Column, Table } from '../../mol-data/db';
|
||||
import { EntityBuilder } from './common/entity';
|
||||
import { File3DG } from '../../mol-io/reader/3dg/parser';
|
||||
|
||||
@@ -16,7 +16,7 @@ import { ElementSymbol } from '../../../mol-model/structure/model/types';
|
||||
import { Entities } from '../../../mol-model/structure/model/properties/common';
|
||||
import { getAtomicDerivedData } from '../../../mol-model/structure/model/properties/utils/atomic-derived';
|
||||
import { AtomSite } from './schema';
|
||||
import { ModelFormat } from '../format';
|
||||
import { ModelFormat } from '../../format';
|
||||
import { SymmetryOperator } from '../../../mol-math/geometry';
|
||||
import { MmcifFormat } from '../mmcif';
|
||||
import { AtomSiteOperatorMappingSchema } from '../../../mol-model/structure/export/categories/atom_site_operator_mapping';
|
||||
|
||||
@@ -10,12 +10,12 @@ import { RuntimeContext } from '../../../mol-task';
|
||||
import UUID from '../../../mol-util/uuid';
|
||||
import { Model } from '../../../mol-model/structure/model/model';
|
||||
import { Entities } from '../../../mol-model/structure/model/properties/common';
|
||||
import { CustomProperties } from '../../../mol-model/structure';
|
||||
import { CustomProperties } from '../../../mol-model/custom-property';
|
||||
import { getAtomicHierarchyAndConformation } from './atomic';
|
||||
import { getCoarse, EmptyCoarse, CoarseData } from './coarse';
|
||||
import { getSequence } from './sequence';
|
||||
import { sortAtomSite } from './sort';
|
||||
import { ModelFormat } from '../format';
|
||||
import { ModelFormat } from '../../format';
|
||||
import { getAtomicRanges } from '../../../mol-model/structure/model/properties/utils/atomic-ranges';
|
||||
import { AtomSite, BasicData } from './schema';
|
||||
import { getProperties } from './properties';
|
||||
|
||||
@@ -12,7 +12,7 @@ import { createModels } from './basic/parser';
|
||||
import { BasicSchema, createBasic } from './basic/schema';
|
||||
import { ComponentBuilder } from './common/component';
|
||||
import { EntityBuilder } from './common/entity';
|
||||
import { ModelFormat } from './format';
|
||||
import { ModelFormat } from '../format';
|
||||
import { CifCore_Database } from '../../mol-io/reader/cif/schema/cif-core';
|
||||
import { CifFrame, CIF } from '../../mol-io/reader/cif';
|
||||
import { Spacegroup, SpacegroupCell } from '../../mol-math/geometry';
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { CustomPropertyDescriptor, Model } from '../../../mol-model/structure';
|
||||
import { ModelFormat } from '../format';
|
||||
import { Model } from '../../../mol-model/structure';
|
||||
import { ModelFormat } from '../../format';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
|
||||
|
||||
class FormatRegistry<T> {
|
||||
private map = new Map<ModelFormat['kind'], (model: Model) => T | undefined>()
|
||||
|
||||
@@ -12,7 +12,7 @@ import { createModels } from './basic/parser';
|
||||
import { BasicSchema, createBasic } from './basic/schema';
|
||||
import { ComponentBuilder } from './common/component';
|
||||
import { EntityBuilder } from './common/entity';
|
||||
import { ModelFormat } from './format';
|
||||
import { ModelFormat } from '../format';
|
||||
import { CubeFile } from '../../mol-io/reader/cube/parser';
|
||||
|
||||
async function getModels(cube: CubeFile, ctx: RuntimeContext): Promise<Model[]> {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { Model } from '../../mol-model/structure/model';
|
||||
import { Task } from '../../mol-task';
|
||||
import { ModelFormat } from './format';
|
||||
import { ModelFormat } from '../format';
|
||||
import { GroFile, GroAtoms } from '../../mol-io/reader/gro/schema';
|
||||
import { Column, Table } from '../../mol-data/db';
|
||||
import { guessElementSymbolString } from './util';
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import { Model } from '../../mol-model/structure/model/model';
|
||||
import { Task } from '../../mol-task';
|
||||
import { ModelFormat } from './format';
|
||||
import { ModelFormat } from '../format';
|
||||
import { CifFrame, CIF } from '../../mol-io/reader/cif';
|
||||
import { mmCIF_Database } from '../../mol-io/reader/cif/schema/mmcif';
|
||||
import { createModels } from './basic/parser';
|
||||
|
||||
@@ -14,7 +14,7 @@ import { createModels } from './basic/parser';
|
||||
import { BasicSchema, createBasic } from './basic/schema';
|
||||
import { ComponentBuilder } from './common/component';
|
||||
import { EntityBuilder } from './common/entity';
|
||||
import { ModelFormat } from './format';
|
||||
import { ModelFormat } from '../format';
|
||||
import { IndexPairBonds } from './property/bonds/index-pair';
|
||||
|
||||
async function getModels(mol: MolFile, ctx: RuntimeContext): Promise<Model[]> {
|
||||
|
||||
98
src/mol-model-formats/structure/mol2.ts
Normal file
98
src/mol-model-formats/structure/mol2.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { Column, Table } from '../../mol-data/db';
|
||||
import { Model } from '../../mol-model/structure/model';
|
||||
import { MoleculeType } from '../../mol-model/structure/model/types';
|
||||
import { RuntimeContext, Task } from '../../mol-task';
|
||||
import { createModels } from './basic/parser';
|
||||
import { BasicSchema, createBasic } from './basic/schema';
|
||||
import { ComponentBuilder } from './common/component';
|
||||
import { EntityBuilder } from './common/entity';
|
||||
import { ModelFormat } from '../format';
|
||||
import { IndexPairBonds } from './property/bonds/index-pair';
|
||||
import { Mol2File } from '../../mol-io/reader/mol2/schema';
|
||||
|
||||
async function getModels(mol2: Mol2File, ctx: RuntimeContext): Promise<Model[]> {
|
||||
const models: Model[] = [];
|
||||
|
||||
for (let i = 0, il = mol2.structures.length; i < il; ++i) {
|
||||
const { atoms, bonds } = mol2.structures[i];
|
||||
|
||||
const A = Column.ofConst('A', atoms.count, Column.Schema.str);
|
||||
|
||||
const atom_site = Table.ofPartialColumns(BasicSchema.atom_site, {
|
||||
auth_asym_id: A,
|
||||
auth_atom_id: Column.asArrayColumn(atoms.atom_type),
|
||||
auth_comp_id: atoms.subst_name,
|
||||
auth_seq_id: atoms.subst_id,
|
||||
Cartn_x: Column.asArrayColumn(atoms.x, Float32Array),
|
||||
Cartn_y: Column.asArrayColumn(atoms.y, Float32Array),
|
||||
Cartn_z: Column.asArrayColumn(atoms.z, Float32Array),
|
||||
id: Column.asArrayColumn(atoms.atom_id),
|
||||
|
||||
label_asym_id: A,
|
||||
label_atom_id: Column.asArrayColumn(atoms.atom_type),
|
||||
label_comp_id: atoms.subst_name,
|
||||
label_seq_id: atoms.subst_id,
|
||||
label_entity_id: Column.ofConst('1', atoms.count, Column.Schema.str),
|
||||
|
||||
occupancy: Column.ofConst(1, atoms.count, Column.Schema.float),
|
||||
type_symbol: Column.asArrayColumn(atoms.atom_name),
|
||||
|
||||
pdbx_PDB_model_num: Column.ofConst(i, atoms.count, Column.Schema.int),
|
||||
}, atoms.count);
|
||||
|
||||
const entityBuilder = new EntityBuilder();
|
||||
entityBuilder.setNames([['MOL', 'Unknown Entity']]);
|
||||
entityBuilder.getEntityId('MOL', MoleculeType.Unknown, 'A');
|
||||
|
||||
const componentBuilder = new ComponentBuilder(atoms.subst_id, atoms.atom_name);
|
||||
for (let i = 0, il = atoms.subst_name.rowCount; i < il; ++i) {
|
||||
componentBuilder.add(atoms.subst_name.value(i), i);
|
||||
}
|
||||
|
||||
const basics = createBasic({
|
||||
entity: entityBuilder.getEntityTable(),
|
||||
chem_comp: componentBuilder.getChemCompTable(),
|
||||
atom_site
|
||||
});
|
||||
|
||||
const _models = await createModels(basics, Mol2Format.create(mol2), ctx);
|
||||
|
||||
if (_models.length > 0) {
|
||||
const indexA = Column.ofIntArray(Column.mapToArray(bonds.origin_atom_id, x => x - 1, Int32Array));
|
||||
const indexB = Column.ofIntArray(Column.mapToArray(bonds.target_atom_id, x => x - 1, Int32Array));
|
||||
const order = Column.ofIntArray(Column.mapToArray(bonds.bond_type, x => x === 'ar' ? 1 : parseInt(x), Int8Array));
|
||||
const pairBonds = IndexPairBonds.fromData({ pairs: { indexA, indexB, order }, count: bonds.count });
|
||||
IndexPairBonds.Provider.set(_models[0], pairBonds);
|
||||
|
||||
models.push(_models[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return models;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
export { Mol2Format };
|
||||
|
||||
type Mol2Format = ModelFormat<Mol2File>
|
||||
|
||||
namespace Mol2Format {
|
||||
export function is(x: ModelFormat): x is Mol2Format {
|
||||
return x.kind === 'mol2';
|
||||
}
|
||||
|
||||
export function create(mol2: Mol2File): Mol2Format {
|
||||
return { kind: 'mol2', name: mol2.name, data: mol2 };
|
||||
}
|
||||
}
|
||||
|
||||
export function trajectoryFromMol2(mol2: Mol2File): Task<Model.Trajectory> {
|
||||
return Task.create('Parse MOL2', ctx => getModels(mol2, ctx));
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { Table, Column } from '../../../mol-data/db';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/structure';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
|
||||
import { mmCIF_Schema } from '../../../mol-io/reader/cif/schema/mmcif';
|
||||
import { CifWriter } from '../../../mol-io/writer/cif';
|
||||
import { FormatPropertyProvider } from '../common/property';
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import { Model } from '../../../../mol-model/structure/model/model';
|
||||
import { BondType } from '../../../../mol-model/structure/model/types';
|
||||
import { CustomPropertyDescriptor } from '../../../../mol-model/structure';
|
||||
import { CustomPropertyDescriptor } from '../../../../mol-model/custom-property';
|
||||
import { mmCIF_Schema } from '../../../../mol-io/reader/cif/schema/mmcif';
|
||||
import { CifWriter } from '../../../../mol-io/writer/cif';
|
||||
import { Table } from '../../../../mol-data/db';
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { CustomPropertyDescriptor } from '../../../../mol-model/structure';
|
||||
import { CustomPropertyDescriptor } from '../../../../mol-model/custom-property';
|
||||
import { IntAdjacencyGraph } from '../../../../mol-math/graph';
|
||||
import { Column } from '../../../../mol-data/db';
|
||||
import { FormatPropertyProvider } from '../../common/property';
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Model } from '../../../../mol-model/structure/model/model';
|
||||
import { Structure } from '../../../../mol-model/structure';
|
||||
import { BondType } from '../../../../mol-model/structure/model/types';
|
||||
import { Column, Table } from '../../../../mol-data/db';
|
||||
import { CustomPropertyDescriptor } from '../../../../mol-model/structure';
|
||||
import { CustomPropertyDescriptor } from '../../../../mol-model/custom-property';
|
||||
import { mmCIF_Schema } from '../../../../mol-io/reader/cif/schema/mmcif';
|
||||
import { SortedArray } from '../../../../mol-data/int';
|
||||
import { CifWriter } from '../../../../mol-io/writer/cif';
|
||||
|
||||
@@ -13,7 +13,7 @@ import { SecondaryStructure } from '../../../mol-model/structure/model/propertie
|
||||
import { Column, Table } from '../../../mol-data/db';
|
||||
import { ChainIndex, ResidueIndex } from '../../../mol-model/structure/model/indexing';
|
||||
import { FormatPropertyProvider } from '../common/property';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/structure';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
|
||||
|
||||
export { ModelSecondaryStructure };
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Spacegroup, SpacegroupCell, SymmetryOperator } from '../../../mol-math/
|
||||
import { Tensor, Vec3, Mat3 } from '../../../mol-math/linear-algebra';
|
||||
import { Symmetry } from '../../../mol-model/structure/model/properties/symmetry';
|
||||
import { createAssemblies } from './assembly';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/structure';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
|
||||
import { FormatPropertyProvider } from '../common/property';
|
||||
import { Table } from '../../../mol-data/db';
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import { guessElementSymbolString } from './util';
|
||||
import { MoleculeType, getMoleculeType } from '../../mol-model/structure/model/types';
|
||||
import { getChainId } from './common/util';
|
||||
import { Task } from '../../mol-task';
|
||||
import { ModelFormat } from './format';
|
||||
import { ModelFormat } from '../format';
|
||||
import { Topology } from '../../mol-model/structure/topology/topology';
|
||||
import { createBasic, BasicSchema } from './basic/schema';
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { VolumeData } from '../../mol-model/volume/data';
|
||||
import { Volume } from '../../mol-model/volume';
|
||||
import { Task } from '../../mol-task';
|
||||
import { SpacegroupCell, Box3D } from '../../mol-math/geometry';
|
||||
import { Tensor, Vec3 } from '../../mol-math/linear-algebra';
|
||||
@@ -13,6 +13,8 @@ import { degToRad } from '../../mol-math/misc';
|
||||
import { getCcp4ValueType } from '../../mol-io/reader/ccp4/parser';
|
||||
import { TypedArrayValueType } from '../../mol-io/common/typed-array';
|
||||
import { arrayMin, arrayRms, arrayMean, arrayMax } from '../../mol-util/array';
|
||||
import { ModelFormat } from '../format';
|
||||
import { CustomProperties } from '../../mol-model/custom-property';
|
||||
|
||||
/** When available (e.g. in MRC files) use ORIGIN records instead of N[CRS]START */
|
||||
export function getCcp4Origin(header: Ccp4Header): Vec3 {
|
||||
@@ -38,8 +40,8 @@ function getTypedArrayCtor(header: Ccp4Header) {
|
||||
throw Error(`${valueType} is not a supported value format.`);
|
||||
}
|
||||
|
||||
export function volumeFromCcp4(source: Ccp4File, params?: { voxelSize?: Vec3, offset?: Vec3, label?: string }): Task<VolumeData> {
|
||||
return Task.create<VolumeData>('Create Volume Data', async ctx => {
|
||||
export function volumeFromCcp4(source: Ccp4File, params?: { voxelSize?: Vec3, offset?: Vec3, label?: string }): Task<Volume> {
|
||||
return Task.create<Volume>('Create Volume', async ctx => {
|
||||
const { header, values } = source;
|
||||
const size = Vec3.create(header.xLength, header.yLength, header.zLength);
|
||||
if (params && params.voxelSize) Vec3.mul(size, size, params.voxelSize);
|
||||
@@ -68,14 +70,35 @@ export function volumeFromCcp4(source: Ccp4File, params?: { voxelSize?: Vec3, of
|
||||
|
||||
return {
|
||||
label: params?.label,
|
||||
transform: { kind: 'spacegroup', cell, fractionalBox: Box3D.create(origin_frac, Vec3.add(Vec3.zero(), origin_frac, dimensions_frac)) },
|
||||
data,
|
||||
dataStats: {
|
||||
min: isNaN(header.AMIN) ? arrayMin(values) : header.AMIN,
|
||||
max: isNaN(header.AMAX) ? arrayMax(values) : header.AMAX,
|
||||
mean: isNaN(header.AMEAN) ? arrayMean(values) : header.AMEAN,
|
||||
sigma: (isNaN(header.ARMS) || header.ARMS === 0) ? arrayRms(values) : header.ARMS
|
||||
}
|
||||
grid: {
|
||||
transform: { kind: 'spacegroup', cell, fractionalBox: Box3D.create(origin_frac, Vec3.add(Vec3.zero(), origin_frac, dimensions_frac)) },
|
||||
cells: data,
|
||||
stats: {
|
||||
min: isNaN(header.AMIN) ? arrayMin(values) : header.AMIN,
|
||||
max: isNaN(header.AMAX) ? arrayMax(values) : header.AMAX,
|
||||
mean: isNaN(header.AMEAN) ? arrayMean(values) : header.AMEAN,
|
||||
sigma: (isNaN(header.ARMS) || header.ARMS === 0) ? arrayRms(values) : header.ARMS
|
||||
},
|
||||
},
|
||||
sourceData: Ccp4Format.create(source),
|
||||
customProperties: new CustomProperties(),
|
||||
_propertyData: Object.create(null),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
export { Ccp4Format };
|
||||
|
||||
type Ccp4Format = ModelFormat<Ccp4File>
|
||||
|
||||
namespace Ccp4Format {
|
||||
export function is(x: ModelFormat): x is Ccp4Format {
|
||||
return x.kind === 'ccp4';
|
||||
}
|
||||
|
||||
export function create(ccp4: Ccp4File): Ccp4Format {
|
||||
return { kind: 'ccp4', name: ccp4.name, data: ccp4 };
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,14 @@
|
||||
|
||||
import { CubeFile } from '../../mol-io/reader/cube/parser';
|
||||
import { Mat4, Tensor } from '../../mol-math/linear-algebra';
|
||||
import { VolumeData } from '../../mol-model/volume/data';
|
||||
import { Volume } from '../../mol-model/volume';
|
||||
import { Task } from '../../mol-task';
|
||||
import { arrayMax, arrayMean, arrayMin, arrayRms } from '../../mol-util/array';
|
||||
import { ModelFormat } from '../format';
|
||||
import { CustomProperties } from '../../mol-model/custom-property';
|
||||
|
||||
export function volumeFromCube(source: CubeFile, params?: { dataIndex?: number, label?: string }): Task<VolumeData> {
|
||||
return Task.create<VolumeData>('Create Volume Data', async () => {
|
||||
export function volumeFromCube(source: CubeFile, params?: { dataIndex?: number, label?: string }): Task<Volume> {
|
||||
return Task.create<Volume>('Create Volume', async () => {
|
||||
const { header, values: sourceValues } = source;
|
||||
const space = Tensor.Space(header.dim, [0, 1, 2], Float64Array);
|
||||
|
||||
@@ -44,14 +46,35 @@ export function volumeFromCube(source: CubeFile, params?: { dataIndex?: number,
|
||||
|
||||
return {
|
||||
label: params?.label,
|
||||
transform: { kind: 'matrix', matrix },
|
||||
data,
|
||||
dataStats: {
|
||||
min: arrayMin(values),
|
||||
max: arrayMax(values),
|
||||
mean: arrayMean(values),
|
||||
sigma: arrayRms(values)
|
||||
}
|
||||
grid: {
|
||||
transform: { kind: 'matrix', matrix },
|
||||
cells: data,
|
||||
stats: {
|
||||
min: arrayMin(values),
|
||||
max: arrayMax(values),
|
||||
mean: arrayMean(values),
|
||||
sigma: arrayRms(values)
|
||||
},
|
||||
},
|
||||
sourceData: CubeFormat.create(source),
|
||||
customProperties: new CustomProperties(),
|
||||
_propertyData: Object.create(null),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
export { CubeFormat };
|
||||
|
||||
type CubeFormat = ModelFormat<CubeFile>
|
||||
|
||||
namespace CubeFormat {
|
||||
export function is(x: ModelFormat): x is CubeFormat {
|
||||
return x.kind === 'cube';
|
||||
}
|
||||
|
||||
export function create(cube: CubeFile): CubeFormat {
|
||||
return { kind: 'cube', name: cube.name, data: cube };
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,15 @@
|
||||
*/
|
||||
|
||||
import { DensityServer_Data_Database } from '../../mol-io/reader/cif/schema/density-server';
|
||||
import { VolumeData } from '../../mol-model/volume/data';
|
||||
import { Volume } from '../../mol-model/volume';
|
||||
import { Task } from '../../mol-task';
|
||||
import { SpacegroupCell, Box3D } from '../../mol-math/geometry';
|
||||
import { Tensor, Vec3 } from '../../mol-math/linear-algebra';
|
||||
import { ModelFormat } from '../format';
|
||||
import { CustomProperties } from '../../mol-model/custom-property';
|
||||
|
||||
function volumeFromDensityServerData(source: DensityServer_Data_Database): Task<VolumeData> {
|
||||
return Task.create<VolumeData>('Create Volume Data', async ctx => {
|
||||
export function volumeFromDensityServerData(source: DensityServer_Data_Database): Task<Volume> {
|
||||
return Task.create<Volume>('Create Volume', async ctx => {
|
||||
const { volume_data_3d_info: info, volume_data_3d: values } = source;
|
||||
const cell = SpacegroupCell.create(
|
||||
info.spacegroup_number.value(0),
|
||||
@@ -34,16 +36,35 @@ function volumeFromDensityServerData(source: DensityServer_Data_Database): Task<
|
||||
const dimensions = Vec3.ofArray(normalizeOrder(info.dimensions.value(0)));
|
||||
|
||||
return {
|
||||
transform: { kind: 'spacegroup', cell, fractionalBox: Box3D.create(origin, Vec3.add(Vec3.zero(), origin, dimensions)) },
|
||||
data,
|
||||
dataStats: {
|
||||
min: info.min_sampled.value(0),
|
||||
max: info.max_sampled.value(0),
|
||||
mean: info.mean_sampled.value(0),
|
||||
sigma: info.sigma_sampled.value(0)
|
||||
}
|
||||
grid: {
|
||||
transform: { kind: 'spacegroup', cell, fractionalBox: Box3D.create(origin, Vec3.add(Vec3.zero(), origin, dimensions)) },
|
||||
cells: data,
|
||||
stats: {
|
||||
min: info.min_sampled.value(0),
|
||||
max: info.max_sampled.value(0),
|
||||
mean: info.mean_sampled.value(0),
|
||||
sigma: info.sigma_sampled.value(0)
|
||||
},
|
||||
},
|
||||
sourceData: DscifFormat.create(source),
|
||||
customProperties: new CustomProperties(),
|
||||
_propertyData: Object.create(null),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export { volumeFromDensityServerData };
|
||||
//
|
||||
|
||||
export { DscifFormat };
|
||||
|
||||
type DscifFormat = ModelFormat<DensityServer_Data_Database>
|
||||
|
||||
namespace DscifFormat {
|
||||
export function is(x: ModelFormat): x is DscifFormat {
|
||||
return x.kind === 'dscif';
|
||||
}
|
||||
|
||||
export function create(dscif: DensityServer_Data_Database): DscifFormat {
|
||||
return { kind: 'dscif', name: dscif._name, data: dscif };
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,18 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { VolumeData } from '../../mol-model/volume/data';
|
||||
import { Volume } from '../../mol-model/volume';
|
||||
import { Task } from '../../mol-task';
|
||||
import { SpacegroupCell, Box3D } from '../../mol-math/geometry';
|
||||
import { Tensor, Vec3 } from '../../mol-math/linear-algebra';
|
||||
import { degToRad } from '../../mol-math/misc';
|
||||
import { Dsn6File } from '../../mol-io/reader/dsn6/schema';
|
||||
import { arrayMin, arrayMax, arrayMean, arrayRms } from '../../mol-util/array';
|
||||
import { ModelFormat } from '../format';
|
||||
import { CustomProperties } from '../../mol-model/custom-property';
|
||||
|
||||
function volumeFromDsn6(source: Dsn6File, params?: { voxelSize?: Vec3, label?: string }): Task<VolumeData> {
|
||||
return Task.create<VolumeData>('Create Volume Data', async ctx => {
|
||||
export function volumeFromDsn6(source: Dsn6File, params?: { voxelSize?: Vec3, label?: string }): Task<Volume> {
|
||||
return Task.create<Volume>('Create Volume', async ctx => {
|
||||
const { header, values } = source;
|
||||
const size = Vec3.create(header.xlen, header.ylen, header.zlen);
|
||||
if (params && params.voxelSize) Vec3.mul(size, size, params.voxelSize);
|
||||
@@ -33,16 +35,35 @@ function volumeFromDsn6(source: Dsn6File, params?: { voxelSize?: Vec3, label?: s
|
||||
|
||||
return {
|
||||
label: params?.label,
|
||||
transform: { kind: 'spacegroup', cell, fractionalBox: Box3D.create(origin_frac, Vec3.add(Vec3.zero(), origin_frac, dimensions_frac)) },
|
||||
data,
|
||||
dataStats: {
|
||||
min: arrayMin(values),
|
||||
max: arrayMax(values),
|
||||
mean: arrayMean(values),
|
||||
sigma: header.sigma !== undefined ? header.sigma : arrayRms(values)
|
||||
}
|
||||
grid: {
|
||||
transform: { kind: 'spacegroup', cell, fractionalBox: Box3D.create(origin_frac, Vec3.add(Vec3.zero(), origin_frac, dimensions_frac)) },
|
||||
cells: data,
|
||||
stats: {
|
||||
min: arrayMin(values),
|
||||
max: arrayMax(values),
|
||||
mean: arrayMean(values),
|
||||
sigma: header.sigma !== undefined ? header.sigma : arrayRms(values)
|
||||
},
|
||||
},
|
||||
sourceData: Dsn6Format.create(source),
|
||||
customProperties: new CustomProperties(),
|
||||
_propertyData: Object.create(null),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export { volumeFromDsn6 };
|
||||
//
|
||||
|
||||
export { Dsn6Format };
|
||||
|
||||
type Dsn6Format = ModelFormat<Dsn6File>
|
||||
|
||||
namespace Dsn6Format {
|
||||
export function is(x: ModelFormat): x is Dsn6Format {
|
||||
return x.kind === 'dsn6';
|
||||
}
|
||||
|
||||
export function create(dsn6: Dsn6File): Dsn6Format {
|
||||
return { kind: 'dsn6', name: dsn6.name, data: dsn6 };
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,14 @@
|
||||
|
||||
import { DxFile } from '../../mol-io/reader/dx/parser';
|
||||
import { Mat4, Tensor } from '../../mol-math/linear-algebra';
|
||||
import { VolumeData } from '../../mol-model/volume/data';
|
||||
import { Volume } from '../../mol-model/volume';
|
||||
import { Task } from '../../mol-task';
|
||||
import { arrayMax, arrayMean, arrayMin, arrayRms } from '../../mol-util/array';
|
||||
import { ModelFormat } from '../format';
|
||||
import { CustomProperties } from '../../mol-model/custom-property';
|
||||
|
||||
export function volumeFromDx(source: DxFile, params?: { label?: string }): Task<VolumeData> {
|
||||
return Task.create<VolumeData>('Create Volume Data', async () => {
|
||||
export function volumeFromDx(source: DxFile, params?: { label?: string }): Task<Volume> {
|
||||
return Task.create<Volume>('Create Volume', async () => {
|
||||
const { header, values } = source;
|
||||
const space = Tensor.Space(header.dim, [0, 1, 2], Float64Array);
|
||||
const data = Tensor.create(space, Tensor.Data1(values));
|
||||
@@ -21,14 +23,35 @@ export function volumeFromDx(source: DxFile, params?: { label?: string }): Task<
|
||||
|
||||
return {
|
||||
label: params?.label,
|
||||
transform: { kind: 'matrix', matrix },
|
||||
data,
|
||||
dataStats: {
|
||||
min: arrayMin(values),
|
||||
max: arrayMax(values),
|
||||
mean: arrayMean(values),
|
||||
sigma: arrayRms(values)
|
||||
}
|
||||
grid: {
|
||||
transform: { kind: 'matrix', matrix },
|
||||
cells: data,
|
||||
stats: {
|
||||
min: arrayMin(values),
|
||||
max: arrayMax(values),
|
||||
mean: arrayMean(values),
|
||||
sigma: arrayRms(values)
|
||||
},
|
||||
},
|
||||
sourceData: DxFormat.create(source),
|
||||
customProperties: new CustomProperties(),
|
||||
_propertyData: Object.create(null),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
export { DxFormat };
|
||||
|
||||
type DxFormat = ModelFormat<DxFile>
|
||||
|
||||
namespace DxFormat {
|
||||
export function is(x: ModelFormat): x is DxFormat {
|
||||
return x.kind === 'dx';
|
||||
}
|
||||
|
||||
export function create(dx: DxFile): DxFormat {
|
||||
return { kind: 'dx', name: dx.name, data: dx };
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { ElementIndex, Model, CustomPropertyDescriptor } from '../../mol-model/structure';
|
||||
import { ElementIndex, Model } from '../../mol-model/structure';
|
||||
import { StructureElement } from '../../mol-model/structure/structure';
|
||||
import { Location } from '../../mol-model/location';
|
||||
import { ThemeDataContext } from '../../mol-theme/theme';
|
||||
@@ -16,6 +16,7 @@ import { OrderedSet } from '../../mol-data/int';
|
||||
import { CustomModelProperty } from './custom-model-property';
|
||||
import { CustomProperty } from './custom-property';
|
||||
import { LociLabelProvider } from '../../mol-plugin-state/manager/loci-label';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
|
||||
export { CustomElementProperty };
|
||||
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { CustomPropertyDescriptor, Model } from '../../mol-model/structure';
|
||||
import { Model } from '../../mol-model/structure';
|
||||
import { ParamDefinition as PD } from '../../mol-util/param-definition';
|
||||
import { ValueBox } from '../../mol-util';
|
||||
import { CustomProperty } from './custom-property';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
|
||||
export { CustomModelProperty };
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { RuntimeContext } from '../../mol-task';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/structure';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
import { ParamDefinition as PD } from '../../mol-util/param-definition';
|
||||
import { ValueBox } from '../../mol-util';
|
||||
import { OrderedMap } from 'immutable';
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { CustomPropertyDescriptor, Structure } from '../../mol-model/structure';
|
||||
import { Structure } from '../../mol-model/structure';
|
||||
import { ParamDefinition as PD } from '../../mol-util/param-definition';
|
||||
import { ValueBox } from '../../mol-util';
|
||||
import { CustomProperty } from './custom-property';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
|
||||
export { CustomStructureProperty };
|
||||
|
||||
|
||||
@@ -7,12 +7,13 @@
|
||||
|
||||
import { ParamDefinition as PD } from '../../mol-util/param-definition';
|
||||
import { ShrakeRupleyComputationParams, AccessibleSurfaceArea } from './accessible-surface-area/shrake-rupley';
|
||||
import { Structure, CustomPropertyDescriptor, Unit } from '../../mol-model/structure';
|
||||
import { Structure, Unit } from '../../mol-model/structure';
|
||||
import { CustomStructureProperty } from '../common/custom-structure-property';
|
||||
import { CustomProperty } from '../common/custom-property';
|
||||
import { QuerySymbolRuntime } from '../../mol-script/runtime/query/compiler';
|
||||
import { CustomPropSymbol } from '../../mol-script/language/symbol';
|
||||
import Type from '../../mol-script/language/type';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
|
||||
export const AccessibleSurfaceAreaParams = {
|
||||
...ShrakeRupleyComputationParams
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { CustomPropertyDescriptor, Structure } from '../../mol-model/structure';
|
||||
import { Structure } from '../../mol-model/structure';
|
||||
import { ParamDefinition as PD } from '../../mol-util/param-definition';
|
||||
import { computeInteractions, Interactions, InteractionsParams as _InteractionsParams } from './interactions/interactions';
|
||||
import { CustomStructureProperty } from '../common/custom-structure-property';
|
||||
import { CustomProperty } from '../common/custom-property';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
|
||||
export const InteractionsParams = {
|
||||
..._InteractionsParams
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Unit } from '../../mol-model/structure/structure';
|
||||
import { CustomStructureProperty } from '../common/custom-structure-property';
|
||||
import { CustomProperty } from '../common/custom-property';
|
||||
import { ModelSecondaryStructure } from '../../mol-model-formats/structure/property/secondary-structure';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/structure/common/custom-property';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
import { Model } from '../../mol-model/structure/model';
|
||||
|
||||
function getSecondaryStructureParams(data?: Structure) {
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { CustomPropertyDescriptor, Structure } from '../../mol-model/structure';
|
||||
import { Structure } from '../../mol-model/structure';
|
||||
import { ParamDefinition as PD } from '../../mol-util/param-definition';
|
||||
import { calcValenceModel, ValenceModel, ValenceModelParams as _ValenceModelParams } from './chemistry/valence-model';
|
||||
import { CustomStructureProperty } from '../common/custom-structure-property';
|
||||
import { CustomProperty } from '../common/custom-property';
|
||||
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
|
||||
|
||||
export const ValenceModelParams = {
|
||||
..._ValenceModelParams
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
import { Model } from '../../../mol-model/structure/model/model';
|
||||
import { Table } from '../../../mol-data/db';
|
||||
import { mmCIF_Schema } from '../../../mol-io/reader/cif/schema/mmcif';
|
||||
import { Unit, CustomPropertyDescriptor } from '../../../mol-model/structure';
|
||||
import { Unit } from '../../../mol-model/structure';
|
||||
import { ElementIndex } from '../../../mol-model/structure/model/indexing';
|
||||
import { FormatPropertyProvider } from '../../../mol-model-formats/structure/common/property';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
|
||||
|
||||
export { ModelCrossLinkRestraint };
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { ModelCrossLinkRestraint } from './format';
|
||||
import { Unit, StructureElement, Structure, CustomPropertyDescriptor, Bond} from '../../../mol-model/structure';
|
||||
import { Unit, StructureElement, Structure, Bond} from '../../../mol-model/structure';
|
||||
import { PairRestraints, PairRestraint } from '../pair-restraints';
|
||||
import { CustomStructureProperty } from '../../common/custom-structure-property';
|
||||
import { CustomProperty } from '../../common/custom-property';
|
||||
@@ -15,6 +15,7 @@ import { Sphere3D } from '../../../mol-math/geometry';
|
||||
import { CentroidHelper } from '../../../mol-math/geometry/centroid-helper';
|
||||
import { bondLabel } from '../../../mol-theme/label';
|
||||
import { Vec3 } from '../../../mol-math/linear-algebra';
|
||||
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
|
||||
|
||||
export type CrossLinkRestraintValue = PairRestraints<CrossLinkRestraint>
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { CifWriter } from '../../../mol-io/writer/cif';
|
||||
import { CifExportContext } from '../export/mmcif';
|
||||
import { QuerySymbolRuntime } from '../../../mol-script/runtime/query/compiler';
|
||||
import { UUID } from '../../../mol-util';
|
||||
import { Asset } from '../../../mol-util/assets';
|
||||
import { CifWriter } from '../mol-io/writer/cif';
|
||||
import { CifExportContext } from './structure/export/mmcif';
|
||||
import { QuerySymbolRuntime } from '../mol-script/runtime/query/compiler';
|
||||
import { UUID } from '../mol-util';
|
||||
import { Asset } from '../mol-util/assets';
|
||||
|
||||
export { CustomPropertyDescriptor, CustomProperties };
|
||||
|
||||
@@ -17,7 +17,6 @@ import { FiniteArray } from '../mol-util/type-helpers';
|
||||
import { BoundaryHelper } from '../mol-math/geometry/boundary-helper';
|
||||
import { stringToWords } from '../mol-util/string';
|
||||
import { Volume } from './volume/volume';
|
||||
import { VolumeData } from './volume';
|
||||
|
||||
/** A Loci that includes every loci */
|
||||
export const EveryLoci = { kind: 'every-loci' as 'every-loci' };
|
||||
@@ -162,12 +161,11 @@ namespace Loci {
|
||||
} else if (loci.kind === 'data-loci') {
|
||||
return loci.getBoundingSphere(boundingSphere);
|
||||
} else if (loci.kind === 'volume-loci') {
|
||||
return VolumeData.getBoundingSphere(loci.volume, boundingSphere);
|
||||
return Volume.getBoundingSphere(loci.volume, boundingSphere);
|
||||
} else if (loci.kind === 'isosurface-loci') {
|
||||
return VolumeData.getBoundingSphere(loci.volume, boundingSphere);
|
||||
return Volume.Isosurface.getBoundingSphere(loci.volume, loci.isoValue, boundingSphere);
|
||||
} else if (loci.kind === 'cell-loci') {
|
||||
// TODO
|
||||
return VolumeData.getBoundingSphere(loci.volume, boundingSphere);
|
||||
return Volume.Cell.getBoundingSphere(loci.volume, loci.indices, boundingSphere);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author David Sehnal <david.sehnal@gmail.com>
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
@@ -24,14 +24,18 @@ namespace Sequence {
|
||||
export interface Base<K extends Kind, Alphabet extends string> {
|
||||
readonly kind: K,
|
||||
readonly length: number,
|
||||
readonly offset: number,
|
||||
|
||||
/** One letter code */
|
||||
readonly code: Column<Alphabet>
|
||||
readonly label: Column<string>
|
||||
|
||||
readonly seqId: Column<number>
|
||||
/** Component id */
|
||||
readonly compId: Column<string>
|
||||
|
||||
/** returns index for given seqId */
|
||||
readonly index: (seqId: number) => number
|
||||
|
||||
/** maps seqId to list of compIds */
|
||||
readonly microHet: ReadonlyMap<number, string[]>
|
||||
}
|
||||
@@ -41,11 +45,6 @@ namespace Sequence {
|
||||
export interface DNA extends Base<Kind.DNA, NuclecicAlphabet> { }
|
||||
export interface Generic extends Base<Kind.Generic, 'X' | '-'> { }
|
||||
|
||||
export function create<K extends Kind, Alphabet extends string>(kind: K, code: Column<Alphabet>, label: Column<string>, seqId: Column<number>, compId: Column<string>, microHet: Map<number, string[]>, offset: number = 0): Base<K, Alphabet> {
|
||||
const length = code.rowCount;
|
||||
return { kind, code, label, seqId, compId, microHet, offset, length };
|
||||
}
|
||||
|
||||
export function getSequenceString(seq: Sequence) {
|
||||
const array = seq.code.toArray();
|
||||
return (array instanceof Array ? array : Array.from(array)).join('');
|
||||
@@ -88,100 +87,60 @@ namespace Sequence {
|
||||
}
|
||||
|
||||
class ResidueNamesImpl<K extends Kind, Alphabet extends string> implements Base<K, Alphabet> {
|
||||
private _offset = 0;
|
||||
private _length = 0;
|
||||
private _microHet: ReadonlyMap<number, string[]> | undefined = void 0;
|
||||
private _code: Column<Alphabet> | undefined = undefined
|
||||
private _label: Column<string> | undefined = undefined
|
||||
public length: number
|
||||
public code: Column<Alphabet>
|
||||
public label: Column<string>
|
||||
public seqId: Column<number>
|
||||
public compId: Column<string>
|
||||
public microHet: ReadonlyMap<number, string[]> = new Map()
|
||||
|
||||
private codeFromName: (name: string) => string
|
||||
|
||||
get code(): Column<Alphabet> {
|
||||
if (this._code !== void 0) return this._code;
|
||||
this.create();
|
||||
return this._code!;
|
||||
private indexMap: Map<number, number>
|
||||
index(seqId: number) {
|
||||
return this.indexMap.get(seqId)!;
|
||||
}
|
||||
|
||||
get label(): Column<string> {
|
||||
if (this._label !== void 0) return this._label;
|
||||
this.create();
|
||||
return this._label!;
|
||||
}
|
||||
constructor(public kind: K, compId: Column<string>, seqId: Column<number>) {
|
||||
const codeFromName = codeProvider(kind);
|
||||
const codes: string[] = [];
|
||||
const compIds: string[] = [];
|
||||
const seqIds: number[] = [];
|
||||
const microHet = new Map<number, string[]>();
|
||||
|
||||
get offset() {
|
||||
if (this._code !== void 0) return this._offset;
|
||||
this.create();
|
||||
return this._offset;
|
||||
}
|
||||
let idx = 0;
|
||||
const indexMap = new Map<number, number>();
|
||||
for (let i = 0, il = seqId.rowCount; i < il; ++i) {
|
||||
const seq_id = seqId.value(i);
|
||||
|
||||
get length() {
|
||||
if (this._code !== void 0) return this._length;
|
||||
this.create();
|
||||
return this._length;
|
||||
}
|
||||
|
||||
get microHet(): ReadonlyMap<number, string[]> {
|
||||
if (this._microHet !== void 0) return this._microHet;
|
||||
this.create();
|
||||
return this._microHet!;
|
||||
}
|
||||
|
||||
private create() {
|
||||
let maxSeqId = 0, minSeqId = Number.MAX_SAFE_INTEGER;
|
||||
for (let i = 0, _i = this.seqId.rowCount; i < _i; i++) {
|
||||
const id = this.seqId.value(i);
|
||||
if (maxSeqId < id) maxSeqId = id;
|
||||
if (id < minSeqId) minSeqId = id;
|
||||
}
|
||||
|
||||
const count = maxSeqId - minSeqId + 1;
|
||||
const sequenceArray = new Array<string>(maxSeqId + 1);
|
||||
const labels = new Array<string[]>(maxSeqId + 1);
|
||||
for (let i = 0; i < count; i++) {
|
||||
sequenceArray[i] = '-';
|
||||
labels[i] = [];
|
||||
}
|
||||
|
||||
const compIds = new Array<string[]>(maxSeqId + 1);
|
||||
for (let i = minSeqId; i <= maxSeqId; ++i) {
|
||||
compIds[i] = [];
|
||||
}
|
||||
|
||||
for (let i = 0, _i = this.seqId.rowCount; i < _i; i++) {
|
||||
const seqId = this.seqId.value(i);
|
||||
const idx = seqId - minSeqId;
|
||||
const name = this.compId.value(i);
|
||||
const code = this.codeFromName(name);
|
||||
// in case of MICROHETEROGENEITY `sequenceArray[idx]` may already be set
|
||||
if (!sequenceArray[idx] || sequenceArray[idx] === '-') {
|
||||
sequenceArray[idx] = code;
|
||||
if (!indexMap.has(seq_id)) {
|
||||
indexMap.set(seq_id, idx);
|
||||
const comp_id = compId.value(i);
|
||||
compIds[idx] = comp_id;
|
||||
seqIds[idx] = seq_id;
|
||||
codes[idx] = codeFromName(comp_id);
|
||||
idx += 1;
|
||||
} else {
|
||||
// micro-heterogeneity
|
||||
if (!microHet.has(seq_id)) {
|
||||
microHet.set(seq_id, [compIds[indexMap.get(seq_id)!], compId.value(i)]);
|
||||
} else {
|
||||
microHet.get(seq_id)!.push(compId.value(i));
|
||||
}
|
||||
}
|
||||
labels[idx].push(code === 'X' ? name : code);
|
||||
compIds[seqId].push(name);
|
||||
}
|
||||
|
||||
const microHet = new Map();
|
||||
for (let i = minSeqId; i <= maxSeqId; ++i) {
|
||||
if (compIds[i].length > 1) microHet.set(i, compIds[i]);
|
||||
const labels: string[] = [];
|
||||
for (let i = 0, il = idx; i < il; ++i) {
|
||||
const mh = microHet.get(seqIds[i]);
|
||||
labels[i] = mh ? `(${mh.join('|')})` : codes[i];
|
||||
}
|
||||
|
||||
this._code = Column.ofStringArray(sequenceArray) as Column<Alphabet>;
|
||||
this._label = Column.ofLambda({
|
||||
value: i => {
|
||||
const l = labels[i];
|
||||
return l.length > 1 ? `(${l.join('|')})` : l.join('');
|
||||
},
|
||||
rowCount: labels.length,
|
||||
schema: Column.Schema.str
|
||||
});
|
||||
this._microHet = microHet;
|
||||
this._offset = minSeqId - 1;
|
||||
this._length = count;
|
||||
}
|
||||
|
||||
constructor(public kind: K, public compId: Column<string>, public seqId: Column<number>) {
|
||||
|
||||
this.codeFromName = codeProvider(kind);
|
||||
this.length = idx;
|
||||
this.code = Column.ofStringArray(codes) as Column<Alphabet>;
|
||||
this.compId = Column.ofStringArray(compIds);
|
||||
this.seqId = Column.ofIntArray(seqIds);
|
||||
this.label = Column.ofStringArray(labels);
|
||||
this.microHet = microHet;
|
||||
this.indexMap = indexMap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,13 +151,17 @@ namespace Sequence {
|
||||
}
|
||||
|
||||
class SequenceRangesImpl<K extends Kind, Alphabet extends string> implements Base<K, Alphabet> {
|
||||
public offset: number
|
||||
public length: number
|
||||
public code: Column<Alphabet>
|
||||
public label: Column<string>
|
||||
public seqId: Column<number>
|
||||
public compId: Column<string>
|
||||
public microHet: ReadonlyMap<number, string[]>
|
||||
public microHet: ReadonlyMap<number, string[]> = new Map()
|
||||
|
||||
private minSeqId: number
|
||||
index(seqId: number) {
|
||||
return seqId - this.minSeqId;
|
||||
}
|
||||
|
||||
constructor(public kind: K, private seqIdStart: Column<number>, private seqIdEnd: Column<number>) {
|
||||
let maxSeqId = 0, minSeqId = Number.MAX_SAFE_INTEGER;
|
||||
@@ -220,8 +183,8 @@ namespace Sequence {
|
||||
});
|
||||
this.compId = Column.ofConst('', count, Column.Schema.str);
|
||||
|
||||
this.offset = minSeqId - 1;
|
||||
this.length = count;
|
||||
this.minSeqId = minSeqId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,5 +9,4 @@ export * from './structure/coordinates';
|
||||
export * from './structure/topology';
|
||||
export * from './structure/model';
|
||||
export * from './structure/structure';
|
||||
export * from './structure/query';
|
||||
export * from './structure/common/custom-property';
|
||||
export * from './structure/query';
|
||||
@@ -15,7 +15,7 @@ import { _chem_comp, _pdbx_chem_comp_identifier, _pdbx_nonpoly_scheme } from './
|
||||
import { Model } from '../model';
|
||||
import { getUniqueEntityIndicesFromStructures, copy_mmCif_category, copy_source_mmCifCategory } from './categories/utils';
|
||||
import { _struct_asym, _entity_poly, _entity_poly_seq } from './categories/sequence';
|
||||
import { CustomPropertyDescriptor } from '../common/custom-property';
|
||||
import { CustomPropertyDescriptor } from '../../custom-property';
|
||||
import { atom_site_operator_mapping } from './categories/atom_site_operator_mapping';
|
||||
import { MmcifFormat } from '../../../mol-model-formats/structure/mmcif';
|
||||
|
||||
@@ -146,7 +146,6 @@ export function encode_mmCIF_categories(encoder: CifWriter.Encoder, structures:
|
||||
if (params?.copyAllCategories && MmcifFormat.is(models[0].sourceData)) {
|
||||
encode_mmCIF_categories_copyAll(encoder, ctx);
|
||||
} else {
|
||||
console.log('default');
|
||||
encode_mmCIF_categories_default(encoder, ctx, params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import StructureSequence from './properties/sequence';
|
||||
import { AtomicHierarchy, AtomicConformation, AtomicRanges } from './properties/atomic';
|
||||
import { CoarseHierarchy, CoarseConformation } from './properties/coarse';
|
||||
import { Entities, ChemicalComponentMap, MissingResidues, StructAsymMap } from './properties/common';
|
||||
import { CustomProperties } from '../common/custom-property';
|
||||
import { CustomProperties } from '../../custom-property';
|
||||
import { SaccharideComponentMap } from '../structure/carbohydrates/constants';
|
||||
import { ModelFormat } from '../../../mol-model-formats/structure/format';
|
||||
import { ModelFormat } from '../../../mol-model-formats/format';
|
||||
import { calcModelCenter } from './util';
|
||||
import { Vec3 } from '../../../mol-math/linear-algebra';
|
||||
import { Mutable } from '../../../mol-util/type-helpers';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user