Skip to content
Snippets Groups Projects
Commit 9e154376 authored by Alexander Rose's avatar Alexander Rose
Browse files

Merge branch 'master' of https://github.com/molstar/molstar into theme-strength

parents e553bf4d 4a9fdbce
No related branches found
No related tags found
No related merge requests found
......@@ -8,17 +8,18 @@ Note that since we don't clearly distinguish between a public and private interf
- Make `PluginContext.initContainer` checkered canvas background optional
- Store URL of downloaded assets to detect zip/gzip based on extension
- Add optional `operator.key`; can be referenced in `IndexPairBonds`
## [v3.23.0] - 2022-10-19
- Add `PluginContext.initContainer/mount/unmount` methods; these should make it easier to reuse a plugin context with both custom and built-in UI
- Add `PluginContext.canvas3dInitialized`
- `createPluginUI` now resolves after the 3d canvas has been initialized
- Change EM Volume Streaming default from `Whote Structure` to `Auto`
- Change EM Volume Streaming default from `Whole Structure` to `Auto`
## [v3.22.0] - 2022-10-17
- Replace `VolumeIsosurfaceParams.pickingGranularity` param with `Volume.PickingGranuality`
- Replace `VolumeIsosurfaceParams.pickingGranularity` param with `Volume.PickingGranuality`
## [v3.21.0] - 2022-10-17
......
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2017-2022 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 { lerp as scalar_lerp } from '../../mol-math/interpolate';
import { defaults } from '../../mol-util';
import { Mat3 } from '../linear-algebra/3d/mat3';
import { Mat4 } from '../linear-algebra/3d/mat4';
import { Quat } from '../linear-algebra/3d/quat';
......@@ -29,11 +29,13 @@ interface SymmetryOperator {
readonly hkl: Vec3,
/** spacegroup symmetry operator index, -1 if not applicable */
readonly spgrOp: number,
/** unique (external) key, -1 if not available */
readonly key: number,
readonly matrix: Mat4,
// cache the inverse of the transform
/** cache the inverse of the transform */
readonly inverse: Mat4,
// optimize the identity case
/** optimize the identity case */
readonly isIdentity: boolean,
/**
......@@ -51,19 +53,20 @@ namespace SymmetryOperator {
export const RotationTranslationEpsilon = 0.005;
export type CreateInfo = { assembly?: SymmetryOperator['assembly'], ncsId?: number, hkl?: Vec3, spgrOp?: number }
export type CreateInfo = { assembly?: SymmetryOperator['assembly'], ncsId?: number, hkl?: Vec3, spgrOp?: number, key?: number }
export function create(name: string, matrix: Mat4, info?: CreateInfo | SymmetryOperator): SymmetryOperator {
let { assembly, ncsId, hkl, spgrOp } = info || { };
let { assembly, ncsId, hkl, spgrOp, key } = info || { };
const _hkl = hkl ? Vec3.clone(hkl) : Vec3();
spgrOp = defaults(spgrOp, -1);
spgrOp = spgrOp ?? -1;
key = key ?? -1;
ncsId = ncsId || -1;
const isIdentity = Mat4.isIdentity(matrix);
const suffix = getSuffix(info, isIdentity);
if (isIdentity) return { name, assembly, matrix, inverse: Mat4.identity(), isIdentity: true, hkl: _hkl, spgrOp, ncsId, suffix };
if (isIdentity) return { name, assembly, matrix, inverse: Mat4.identity(), isIdentity: true, hkl: _hkl, spgrOp, ncsId, suffix, key };
if (!Mat4.isRotationAndTranslation(matrix, RotationTranslationEpsilon)) {
console.warn(`Symmetry operator (${name}) should be a composition of rotation and translation.`);
}
return { name, assembly, matrix, inverse: Mat4.invert(Mat4(), matrix), isIdentity: false, hkl: _hkl, spgrOp, ncsId, suffix };
return { name, assembly, matrix, inverse: Mat4.invert(Mat4(), matrix), isIdentity: false, hkl: _hkl, spgrOp, key, ncsId, suffix };
}
function isSymmetryOperator(x: any): x is SymmetryOperator {
......
......@@ -14,6 +14,8 @@ import { ElementIndex } from '../../../../mol-model/structure';
export type IndexPairsProps = {
readonly key: ArrayLike<number>
readonly operatorA: ArrayLike<number>
readonly operatorB: ArrayLike<number>
readonly order: ArrayLike<number>
readonly distance: ArrayLike<number>
readonly flag: ArrayLike<BondType.Flag>
......@@ -24,18 +26,22 @@ export type IndexPairBonds = { bonds: IndexPairs, maxDistance: number }
function getGraph(indexA: ArrayLike<ElementIndex>, indexB: ArrayLike<ElementIndex>, props: Partial<IndexPairsProps>, count: number): IndexPairs {
const builder = new IntAdjacencyGraph.EdgeBuilder(count, indexA, indexB);
const key = new Int32Array(builder.slotCount);
const operatorA = new Array(builder.slotCount);
const operatorB = new Array(builder.slotCount);
const order = new Int8Array(builder.slotCount);
const distance = new Array(builder.slotCount);
const flag = new Array(builder.slotCount);
for (let i = 0, _i = builder.edgeCount; i < _i; i++) {
builder.addNextEdge();
builder.assignProperty(key, props.key ? props.key[i] : -1);
builder.assignProperty(operatorA, props.operatorA ? props.operatorA[i] : -1);
builder.assignProperty(operatorB, props.operatorB ? props.operatorB[i] : -1);
builder.assignProperty(order, props.order ? props.order[i] : 1);
builder.assignProperty(distance, props.distance ? props.distance[i] : -1);
builder.assignProperty(flag, props.flag ? props.flag[i] : BondType.Flag.Covalent);
}
return builder.createGraph({ key, order, distance, flag });
return builder.createGraph({ key, operatorA, operatorB, order, distance, flag });
}
export namespace IndexPairBonds {
......@@ -50,6 +56,10 @@ export namespace IndexPairBonds {
indexA: Column<number>,
indexB: Column<number>,
key?: Column<number>,
/** Operator key for indexA. Used in bond computation. */
operatorA?: Column<number>,
/** Operator key for indexB. Used in bond computation. */
operatorB?: Column<number>,
order?: Column<number>,
/**
* Useful for bonds in periodic cells. That is, only bonds within the given
......@@ -83,11 +93,13 @@ export namespace IndexPairBonds {
const indexA = pairs.indexA.toArray() as ArrayLike<ElementIndex>;
const indexB = pairs.indexB.toArray() as ArrayLike<ElementIndex>;
const key = pairs.key && pairs.key.toArray();
const operatorA = pairs.operatorA && pairs.operatorA.toArray();
const operatorB = pairs.operatorB && pairs.operatorB.toArray();
const order = pairs.order && pairs.order.toArray();
const distance = pairs.distance && pairs.distance.toArray();
const flag = pairs.flag && pairs.flag.toArray();
return {
bonds: getGraph(indexA, indexB, { key, order, distance, flag }, count),
bonds: getGraph(indexA, indexB, { key, operatorA, operatorB, order, distance, flag }, count),
maxDistance: p.maxDistance
};
}
......
......@@ -155,6 +155,6 @@ class QueryContextBondInfo<U extends Unit = Unit> {
}
get length() {
return StructureElement.Location.distance(this.a, this. b);
return StructureElement.Location.distance(this.a, this.b);
}
}
\ No newline at end of file
/**
* Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2017-2022 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>
......@@ -173,6 +173,7 @@ const unit = {
multiChain: p(l => Unit.Traits.is(l.unit.traits, Unit.Trait.MultiChain)),
object_primitive: p(l => l.unit.objectPrimitive),
operator_name: p(l => l.unit.conformation.operator.name),
operator_key: p(l => l.unit.conformation.operator.key),
model_index: p(l => l.unit.model.modelNum),
model_label: p(l => l.unit.model.label),
model_entry_id: p(l => l.unit.model.entryId),
......
......@@ -71,6 +71,8 @@ function findPairBonds(unitA: Unit.Atomic, unitB: Unit.Atomic, props: BondComput
const testDistanceSq = (bRadius + maxRadius) * (bRadius + maxRadius);
builder.startUnitPair(unitA.id, unitB.id);
const opKeyA = unitA.conformation.operator.key;
const opKeyB = unitB.conformation.operator.key;
for (let _aI = 0 as StructureElement.UnitIndex; _aI < atomCount; _aI++) {
const aI = atomsA[_aI];
......@@ -80,7 +82,7 @@ function findPairBonds(unitA: Unit.Atomic, unitB: Unit.Atomic, props: BondComput
if (!props.forceCompute && indexPairs) {
const { maxDistance } = indexPairs;
const { offset, b, edgeProps: { order, distance, flag, key } } = indexPairs.bonds;
const { offset, b, edgeProps: { order, distance, flag, key, operatorA, operatorB } } = indexPairs.bonds;
const srcA = sourceIndex.value(aI);
const aeI = getElementIdx(type_symbolA.value(aI));
......@@ -90,6 +92,10 @@ function findPairBonds(unitA: Unit.Atomic, unitB: Unit.Atomic, props: BondComput
const _bI = SortedArray.indexOf(unitB.elements, bI) as StructureElement.UnitIndex;
if (_bI < 0) continue;
const opA = operatorA[i];
const opB = operatorB[i];
if ((opA >= 0 && opA !== opKeyA) || (opB >= 0 && opB !== opKeyB)) continue;
const beI = getElementIdx(type_symbolA.value(bI));
const d = distance[i];
......
......@@ -55,7 +55,7 @@ function findIndexPairBonds(unit: Unit.Atomic) {
const { type_symbol } = unit.model.atomicHierarchy.atoms;
const atomCount = unit.elements.length;
const { maxDistance } = indexPairs;
const { offset, b, edgeProps: { order, distance, flag, key } } = indexPairs.bonds;
const { offset, b, edgeProps: { order, distance, flag, key, operatorA, operatorB } } = indexPairs.bonds;
const { atomSourceIndex: sourceIndex } = unit.model.atomicHierarchy;
const { invertedIndex } = Model.getInvertedAtomSourceIndex(unit.model);
......@@ -66,6 +66,8 @@ function findIndexPairBonds(unit: Unit.Atomic) {
const orders: number[] = [];
const keys: number[] = [];
const opKey = unit.conformation.operator.key;
for (let _aI = 0 as StructureElement.UnitIndex; _aI < atomCount; _aI++) {
const aI = atoms[_aI];
const aeI = getElementIdx(type_symbol.value(aI));
......@@ -80,6 +82,10 @@ function findIndexPairBonds(unit: Unit.Atomic) {
const _bI = SortedArray.indexOf(unit.elements, bI) as StructureElement.UnitIndex;
if (_bI < 0) continue;
const opA = operatorA[i];
const opB = operatorB[i];
if ((opA >= 0 && opA !== opKey) || (opB >= 0 && opB !== opKey)) continue;
const beI = getElementIdx(type_symbol.value(bI));
const d = distance[i];
......
......@@ -273,6 +273,7 @@ const atomProperty = {
sourceIndex: atomProp(Type.Num, 'Index of the atom/element in the input file.'),
operatorName: atomProp(Type.Str, 'Name of the symmetry operator applied to this element.'),
operatorKey: atomProp(Type.Num, 'Key of the symmetry operator applied to this element.'),
modelIndex: atomProp(Type.Num, 'Index of the model in the input file.'),
modelLabel: atomProp(Type.Str, 'Label/header of the model in the input file.')
},
......
......@@ -299,6 +299,7 @@ const symbols = [
D(MolScript.structureQuery.atomProperty.core.z, atomProp(StructureProperties.atom.z)),
D(MolScript.structureQuery.atomProperty.core.sourceIndex, atomProp(StructureProperties.atom.sourceIndex)),
D(MolScript.structureQuery.atomProperty.core.operatorName, atomProp(StructureProperties.unit.operator_name)),
D(MolScript.structureQuery.atomProperty.core.operatorKey, atomProp(StructureProperties.unit.operator_key)),
D(MolScript.structureQuery.atomProperty.core.modelIndex, atomProp(StructureProperties.unit.model_index)),
D(MolScript.structureQuery.atomProperty.core.modelLabel, atomProp(StructureProperties.unit.model_label)),
D(MolScript.structureQuery.atomProperty.core.atomKey, (ctx, xs) => {
......
/**
* Copyright (c) 2018 Mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2018-2022 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 { UniqueArray } from '../../../mol-data/generic';
......@@ -205,6 +206,7 @@ export const SymbolTable = [
Alias(MolScript.structureQuery.atomProperty.core.z, 'atom.z'),
Alias(MolScript.structureQuery.atomProperty.core.sourceIndex, 'atom.src-index'),
Alias(MolScript.structureQuery.atomProperty.core.operatorName, 'atom.op-name'),
Alias(MolScript.structureQuery.atomProperty.core.operatorKey, 'atom.op-key'),
Alias(MolScript.structureQuery.atomProperty.core.modelIndex, 'atom.model-index'),
Alias(MolScript.structureQuery.atomProperty.core.modelLabel, 'atom.model-label'),
Alias(MolScript.structureQuery.atomProperty.core.atomKey, 'atom.key'),
......@@ -253,6 +255,7 @@ export const SymbolTable = [
'Bond Properties',
Alias(MolScript.structureQuery.bondProperty.order, 'bond.order'),
Alias(MolScript.structureQuery.bondProperty.length, 'bond.length'),
Alias(MolScript.structureQuery.bondProperty.key, 'bond.key'),
Alias(MolScript.structureQuery.bondProperty.atomA, 'bond.atom-a'),
Alias(MolScript.structureQuery.bondProperty.atomB, 'bond.atom-b'),
Macro(MSymbol('bond.is', Arguments.List(StructureQueryTypes.BondFlag), Type.Bool,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment