Compare commits

...

12 Commits

Author SHA1 Message Date
Alexander Rose
3415fe0847 0.7.1-dev.2 2020-05-09 11:54:33 -07:00
Alexander Rose
1569958a29 debug-mode url param, canvas3d console stats 2020-05-09 11:52:09 -07:00
Alexander Rose
3543faa0c2 fix snapshot loading 2020-05-09 11:03:58 -07:00
Alexander Rose
251dbf3877 0.7.1-dev.1 2020-05-08 15:30:57 -07:00
Alexander Rose
32d35efef0 add grid size to volume transform description and incr version 2020-05-08 15:27:39 -07:00
Alexander Rose
8b6428a61d 0.7.0 2020-05-08 10:45:43 -07:00
Alexander Rose
dda43370cf add setProductionMode, setDebugMode exports 2020-05-08 10:42:38 -07:00
Alexander Rose
92c1e979c0 add version to viewer module export 2020-05-08 10:36:26 -07:00
Alexander Rose
ad38a33943 basic support for aligning coarse structures 2020-05-08 10:20:09 -07:00
Alexander Rose
88c276a4c7 inline option for ToggleSelectionModeButton 2020-05-07 16:16:32 -07:00
Alexander Rose
0a3d19235d 0.7.0-dev.21 2020-05-06 20:16:36 -07:00
Alexander Rose
0d90fd1f06 tweak version script
- so the build contains the correct version number
2020-05-06 20:14:52 -07:00
12 changed files with 68 additions and 35 deletions

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "molstar",
"version": "0.7.0-dev.20",
"version": "0.7.1-dev.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "molstar",
"version": "0.7.0-dev.20",
"version": "0.7.1-dev.2",
"description": "A comprehensive macromolecular library.",
"homepage": "https://github.com/molstar/molstar#readme",
"repository": {
@@ -34,7 +34,8 @@
"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 && npm run build",
"preversion": "npm run test",
"version": "npm run build",
"postversion": "git push && git push --tags"
},
"files": [

View File

@@ -45,6 +45,9 @@
return decodeURIComponent(((window.location.search || '').match(r) || [])[1] || '');
}
var debugMode = getParam('debug-mode', '[^&]+').trim() === '1';
if (debugMode) molstar.setDebugMode(debugMode);
var hideControls = getParam('hide-controls', '[^&]+').trim() === '1';
var pdbProvider = getParam('pdb-provider', '[^&]+').trim().toLowerCase();
var emdbProvider = getParam('emdb-provider', '[^&]+').trim().toLowerCase();
@@ -59,7 +62,7 @@
if (snapshotId) viewer.setRemoteSnapshot(snapshotId);
var snapshotUrl = getParam('snapshot-url', '[^&]+').trim();
var snapshotUrlType = getParam('snapshot-url-type', '[^&]+').toLowerCase().trim();
var snapshotUrlType = getParam('snapshot-url-type', '[^&]+').toLowerCase().trim() || 'molj';
if (snapshotUrl && snapshotUrlType) viewer.loadSnapshotFromUrl(snapshotUrl, snapshotUrlType);
var structureUrl = getParam('structure-url', '[^&]+').trim();

View File

@@ -23,8 +23,12 @@ 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');
export { PLUGIN_VERSION as version } from '../../mol-plugin/version';
export { setProductionMode, setDebugMode } from '../../mol-util/debug';
const Extensions = {
'cellpack': PluginSpec.Behavior(CellPack),
'pdbe-structure-quality-report': PluginSpec.Behavior(PDBeStructureQualityReport),

View File

@@ -362,10 +362,19 @@ namespace Canvas3D {
camera.setState({ radiusMax: scene.boundingSphere.radius }, 0);
reprCount.next(reprRenderObjects.size);
if (isDebugMode) consoleStats();
return true;
}
function consoleStats() {
console.table(scene.renderables.map(r => ({
drawCount: r.values.drawCount.ref.value,
instanceCount: r.values.instanceCount.ref.value,
materialId: r.materialId,
})));
}
function add(repr: Representation.Any) {
registerAutoUpdate(repr);
@@ -384,6 +393,7 @@ namespace Canvas3D {
reprRenderObjects.set(repr, newRO);
scene.update(repr.renderObjects, false);
if (isDebugMode) consoleStats();
}
function remove(repr: Representation.Any) {
@@ -394,6 +404,7 @@ namespace Canvas3D {
renderObjects.forEach(o => scene.remove(o));
reprRenderObjects.delete(repr);
scene.update(repr.renderObjects, false, true);
if (isDebugMode) consoleStats();
}
}

View File

@@ -24,16 +24,26 @@ namespace AlignSequences {
function createSeqIdIndicesMap(element: StructureElement.Loci.Element) {
const seqIds = new Map<number, StructureElement.UnitIndex[]>();
if (!Unit.isAtomic(element.unit)) return seqIds;
const { label_seq_id } = element.unit.model.atomicHierarchy.residues;
const { residueIndex } = element.unit;
for (let i = 0, il = OrderedSet.size(element.indices); i < il; ++i) {
const uI = OrderedSet.getAt(element.indices, i);
const eI = element.unit.elements[uI];
const seqId = label_seq_id.value(residueIndex[eI]);
if (seqIds.has(seqId)) seqIds.get(seqId)!.push(uI);
else seqIds.set(seqId, [uI]);
if (Unit.isAtomic(element.unit)) {
const { label_seq_id } = element.unit.model.atomicHierarchy.residues;
const { residueIndex } = element.unit;
for (let i = 0, il = OrderedSet.size(element.indices); i < il; ++i) {
const uI = OrderedSet.getAt(element.indices, i);
const eI = element.unit.elements[uI];
const seqId = label_seq_id.value(residueIndex[eI]);
if (seqIds.has(seqId)) seqIds.get(seqId)!.push(uI);
else seqIds.set(seqId, [uI]);
}
} else if (Unit.isCoarse(element.unit)) {
const { seq_id_begin } = Unit.isSpheres(element.unit)
? element.unit.model.coarseHierarchy.spheres
: element.unit.model.coarseHierarchy.gaussians;
for (let i = 0, il = OrderedSet.size(element.indices); i < il; ++i) {
const uI = OrderedSet.getAt(element.indices, i);
const eI = element.unit.elements[uI];
const seqId = seq_id_begin.value(eI);
seqIds.set(seqId, [uI]);
}
}
return seqIds;
}

View File

@@ -231,6 +231,8 @@ class PluginStateSnapshotManager extends StatefulPluginComponent<{
if (PluginStateSnapshotManager.isStateSnapshot(snapshot)) {
return this.setStateSnapshot(snapshot);
} else if (PluginStateSnapshotManager.isStateSnapshot(snapshot.data)) {
return this.setStateSnapshot(snapshot.data);
} else {
this.plugin.state.setSnapshot(snapshot);
}
@@ -330,7 +332,7 @@ namespace PluginStateSnapshotManager {
snapshot: PluginState.Snapshot
}
export function Entry(snapshot: PluginState.Snapshot, params: {name?: string, description?: string }): Entry {
export function Entry(snapshot: PluginState.Snapshot, params: { name?: string, description?: string }): Entry {
return { timestamp: +new Date(), snapshot, ...params };
}

View File

@@ -42,7 +42,7 @@ const VolumeFromCcp4 = PluginStateTransform.BuiltIn({
apply({ a, params }) {
return Task.create('Create volume from CCP4/MRC/MAP', async ctx => {
const volume = await volumeFromCcp4(a.data, { ...params, label: a.data.name || a.label }).runInContext(ctx);
const props = { label: volume.label || 'Volume', description: 'Volume' };
const props = { label: volume.label || 'Volume', description: `Volume ${a.data.header.NX}\u00D7${a.data.header.NX}\u00D7${a.data.header.NX}` };
return new SO.Volume.Data(volume, props);
});
}
@@ -63,7 +63,7 @@ const VolumeFromDsn6 = PluginStateTransform.BuiltIn({
apply({ a, params }) {
return Task.create('Create volume from DSN6/BRIX', async ctx => {
const volume = await volumeFromDsn6(a.data, { ...params, label: a.data.name || a.label }).runInContext(ctx);
const props = { label: volume.label || 'Volume', description: 'Volume' };
const props = { label: volume.label || 'Volume', description: `Volume ${a.data.header.xExtent}\u00D7${a.data.header.yExtent}\u00D7${a.data.header.zExtent}` };
return new SO.Volume.Data(volume, props);
});
}
@@ -85,7 +85,7 @@ const VolumeFromCube = PluginStateTransform.BuiltIn({
apply({ a, params }) {
return Task.create('Create volume from Cube', async ctx => {
const volume = await volumeFromCube(a.data, { ...params, label: a.data.name || a.label }).runInContext(ctx);
const props = { label: volume.label || 'Volume', description: 'Volume' };
const props = { label: volume.label || 'Volume', description: `Volume ${a.data.header.dim[0]}\u00D7${a.data.header.dim[1]}\u00D7${a.data.header.dim[2]}` };
return new SO.Volume.Data(volume, props);
});
}
@@ -102,8 +102,7 @@ const VolumeFromDx = PluginStateTransform.BuiltIn({
return Task.create('Parse DX', async ctx => {
console.log(a);
const volume = await volumeFromDx(a.data, { label: a.data.name || a.label }).runInContext(ctx);
console.log(volume);
const props = { label: volume.label || 'Volume', description: 'Volume' };
const props = { label: volume.label || 'Volume', description: `Volume ${a.data.header.dim[0]}\u00D7${a.data.header.dim[1]}\u00D7${a.data.header.dim[2]}` };
return new SO.Volume.Data(volume, props);
});
}
@@ -135,7 +134,8 @@ const VolumeFromDensityServerCif = PluginStateTransform.BuiltIn({
if (!block) throw new Error(`Data block '${[header]}' not found.`);
const densityServerCif = CIF.schema.densityServer(block);
const volume = await volumeFromDensityServerData(densityServerCif).runInContext(ctx);
const props = { label: densityServerCif.volume_data_3d_info.name.value(0), description: `${densityServerCif.volume_data_3d_info.name.value(0)}` };
const [x, y, z] = volume.grid.cells.space.dimensions;
const props = { label: densityServerCif.volume_data_3d_info.name.value(0), description: `Volume ${x}\u00D7${y}\u00D7${z}` };
return new SO.Volume.Data(volume, props);
});
}

View File

@@ -172,7 +172,7 @@ export class MeasurementControls extends PurePluginUIComponent<{}, { isBusy: boo
{entries}
</div>}
{entries.length === 0 && <div className='msp-control-offset msp-help-text'>
<div className='msp-help-description' style={{ padding: 0 }}><Icon svg={HelpOutline} inline />Add one or more selections <ToggleSelectionModeButton /></div>
<div className='msp-help-description'><Icon svg={HelpOutline} inline />Add one or more selections (toggle <ToggleSelectionModeButton inline /> mode)</div>
</div>}
</>;
}

View File

@@ -30,7 +30,7 @@ import Structure from '../../mol-model/structure/structure/structure';
import { ViewportHelpContent, HelpGroup, HelpText } from '../viewport/help';
export class ToggleSelectionModeButton extends PurePluginUIComponent {
export class ToggleSelectionModeButton extends PurePluginUIComponent<{ inline?: boolean }> {
componentDidMount() {
this.subscribe(this.plugin.events.canvas3d.settingsUpdated, () => this.forceUpdate());
this.subscribe(this.plugin.layout.events.updated, () => this.forceUpdate());
@@ -42,7 +42,10 @@ export class ToggleSelectionModeButton extends PurePluginUIComponent {
}
render() {
return <IconButton svg={CursorSvg} onClick={this._toggleSelMode} title={'Toggle Selection Mode'} style={{ background: 'transparent' }} toggleState={this.plugin.selectionMode} />;
const style = this.props.inline
? { background: 'transparent', width: 'auto', height: 'auto', lineHeight: 'unset' }
: { background: 'transparent' };
return <IconButton svg={CursorSvg} onClick={this._toggleSelMode} title={'Toggle Selection Mode'} style={style} toggleState={this.plugin.selectionMode} />;
}
}

View File

@@ -278,7 +278,7 @@ export class SuperpositionControls extends PurePluginUIComponent<{}, Superpositi
{entries.map((e, i) => this.lociEntry(e, i))}
</div>}
{entries.length < 2 && <div className='msp-control-offset msp-help-text'>
<div className='msp-help-description'><Icon svg={HelpOutline} inline />Add 2 or more selections <ToggleSelectionModeButton /> from separate structures. Selections must be limited to single polymer chains or residues therein.</div>
<div className='msp-help-description'><Icon svg={HelpOutline} inline />Add 2 or more selections (toggle <ToggleSelectionModeButton inline /> mode) from separate structures. Selections must be limited to single polymer chains or residues therein.</div>
</div>}
{entries.length > 1 && <Button title='Superpose structures by selected chains.' className='msp-btn-commit msp-btn-commit-on' onClick={this.superposeChains} style={{ marginTop: '1px' }}>
Superpose
@@ -293,7 +293,7 @@ export class SuperpositionControls extends PurePluginUIComponent<{}, Superpositi
{entries.map((e, i) => this.atomsLociEntry(e, i))}
</div>}
{entries.length < 2 && <div className='msp-control-offset msp-help-text'>
<div className='msp-help-description'><Icon svg={HelpOutline} inline />Add 1 or more selections <ToggleSelectionModeButton /> from
<div className='msp-help-description'><Icon svg={HelpOutline} inline />Add 1 or more selections (toggle <ToggleSelectionModeButton inline /> mode) from
separate structures. Selections must be limited to single atoms.</div>
</div>}
{entries.length > 1 && <Button title='Superpose structures by selected atoms.' className='msp-btn-commit msp-btn-commit-on' onClick={this.superposeAtoms} style={{ marginTop: '1px' }}>

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -16,13 +16,12 @@ let isProductionMode = process.env.NODE_ENV === 'production';
*/
let isDebugMode = process.env.DEBUG === '*' || process.env.DEBUG === 'molstar';
if (typeof window !== 'undefined' && !(window as any).setMolStarDebugMode) {
try {
(window as any).setMolStarDebugMode = function setMolStarDebugMode(isDebug?: boolean, isProduction?: boolean) {
if (typeof isDebug !== 'undefined') isDebugMode = isDebug;
if (typeof isProduction !== 'undefined') isProductionMode = isProduction;
};
} catch { }
export { isProductionMode, isDebugMode };
export function setProductionMode(value?: boolean) {
if (typeof value !== 'undefined') isProductionMode = value;
}
export { isProductionMode, isDebugMode };
export function setDebugMode(value?: boolean) {
if (typeof value !== 'undefined') isDebugMode = value;
}