diff --git a/src/mol-math/linear-algebra/3d.ts b/src/mol-math/linear-algebra/3d.ts index ed1a97900112fc6c59ce8ca0381bdad713cfdc1e..1609b99cf653e3f37380a6f5193cd26cd829551f 100644 --- a/src/mol-math/linear-algebra/3d.ts +++ b/src/mol-math/linear-algebra/3d.ts @@ -439,6 +439,11 @@ export namespace Mat4 { return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; } + /** + * Check if the matrix has the form + * [ Rotation Translation ] + * [ 0 1 ] + */ export function isRotationAndTranslation(a: Mat4, eps?: number) { return _isRotationAndTranslation(a, typeof eps !== 'undefined' ? eps : EPSILON.Value) } diff --git a/src/mol-model/structure/model.ts b/src/mol-model/structure/model.ts index 4c00023170d18a755b948749fd82cb6f70b553f3..c53fd0986639873923cf30fbceba2d6010233741 100644 --- a/src/mol-model/structure/model.ts +++ b/src/mol-model/structure/model.ts @@ -7,6 +7,6 @@ import Model from './model/model' import * as Types from './model/types' import Format from './model/format' -import Symmetry from './model/properties/symmetry' +import ModelSymmetry from './model/properties/symmetry' -export { Model, Types, Format, Symmetry } \ No newline at end of file +export { Model, Types, Format, ModelSymmetry } \ No newline at end of file diff --git a/src/mol-model/structure/model/properties/symmetry.ts b/src/mol-model/structure/model/properties/symmetry.ts index 994d358de19302a17bd86de951c48b70c0526103..38303de0e1951c84397c3aad3621a8a6b4055730 100644 --- a/src/mol-model/structure/model/properties/symmetry.ts +++ b/src/mol-model/structure/model/properties/symmetry.ts @@ -21,7 +21,7 @@ export class Assembly { readonly details: string; private _operators: OperatorGroups; - get operators(): OperatorGroups { + get operatorGroups(): OperatorGroups { if (this._operators) return this._operators; this._operators = this.operatorsProvider(); return this._operators; diff --git a/src/mol-model/structure/structure.ts b/src/mol-model/structure/structure.ts index 4fe835cfaffe28eeb60b503fc14b6e713f2074b5..0d5c8bad60f2489276a28cc76d0ee641635cd916 100644 --- a/src/mol-model/structure/structure.ts +++ b/src/mol-model/structure/structure.ts @@ -8,5 +8,6 @@ import Atom from './structure/atom' import AtomSet from './structure/atom/set' import Structure from './structure/structure' import Unit from './structure/unit' +import Symmetry from './structure/symmetry' -export { Atom, AtomSet, Structure, Unit } \ No newline at end of file +export { Atom, AtomSet, Structure, Unit, Symmetry } \ No newline at end of file diff --git a/src/mol-model/structure/structure/symmetry.ts b/src/mol-model/structure/structure/symmetry.ts new file mode 100644 index 0000000000000000000000000000000000000000..2a4ef8c37c4f3a24b67391554806f2efd4489964 --- /dev/null +++ b/src/mol-model/structure/structure/symmetry.ts @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author David Sehnal <david.sehnal@gmail.com> + */ + +import Structure from './structure' +import AtomSet from './atom/set' +import Unit from './unit' +import { Selection } from '../query' +import { ModelSymmetry } from '../model' + +namespace Symmetry { + export const buildAssembly = buildAssemblyImpl; +} + +export default Symmetry; + +function buildAssemblyImpl(structure: Structure, name: string) { + const models = Structure.getModels(structure); + if (models.length !== 1) throw new Error('Can only build assemblies from structures based on 1 model.'); + + const assembly = ModelSymmetry.findAssembly(models[0], name); + if (!assembly) throw new Error(`Assembly '${name}' is not defined.`); + + const { operatorGroups } = assembly; + + const assemblyUnits = Object.create(null); + const assemblyAtoms = Object.create(null); + + for (const g of operatorGroups) { + const selection = g.selector(structure); + if (Selection.structureCount(selection) === 0) continue; + const { units, atoms } = Selection.union(selection); + + const unitIds = AtomSet.unitIds(atoms); + + for (const oper of g.operators) { + for (let uI = 0, _uI = unitIds.length; uI < _uI; uI++) { + const unitId = unitIds[uI]; + const unit = units[unitId]; + + const newUnit = Unit.create(unit.model, oper); + assemblyUnits[newUnit.id] = newUnit; + assemblyAtoms[newUnit.id] = AtomSet.unitGetByIndex(atoms, uI); + } + } + } + + return Structure.create(assemblyUnits, AtomSet.create(assemblyAtoms)); +} \ No newline at end of file diff --git a/src/perf-tests/structure.ts b/src/perf-tests/structure.ts index e610c871f65b7046ade38a2c9fbe3d763dc99518..5a7e48b41e5534485381b778dd5bf37ae5227763 100644 --- a/src/perf-tests/structure.ts +++ b/src/perf-tests/structure.ts @@ -10,7 +10,7 @@ import * as util from 'util' import * as fs from 'fs' import CIF from 'mol-io/reader/cif' -import { Structure, Model, Queries as Q, Atom, AtomSet, Selection } from 'mol-model/structure' +import { Structure, Model, Queries as Q, Atom, AtomSet, Selection, Symmetry } from 'mol-model/structure' import { OrderedSet as OrdSet, Segmentation } from 'mol-data/int' import to_mmCIF from 'mol-model/structure/export/mmcif' @@ -241,6 +241,13 @@ export namespace PropertyAccess { console.log(to_mmCIF('test', s)); } + export function testAssembly(s: Structure) { + const a = Symmetry.buildAssembly(s, '1'); + fs.writeFileSync('e:/test/molstar/1hrv_assembly.cif', to_mmCIF('test', a, false)); + console.log('exported'); + //write(a); + } + export async function run() { //const { structures, models, mmcif } = await readCIF('./examples/1cbs_full.bcif'); //const { structures, models, mmcif } = await readCIF('e:/test/quick/3j3q_full.bcif'); @@ -250,6 +257,9 @@ export namespace PropertyAccess { //console.log(mmcif.pdbx_struct_oper_list.matrix.toArray()); // console.log(mmcif.pdbx_struct_oper_list.vector.toArray()); + testAssembly(structures[0]); + throw ''; + console.log(models[0].symmetry.assemblies);