diff --git a/src/mol-math/geometry/spacegroup/construction.ts b/src/mol-math/geometry/spacegroup/construction.ts index fad17c498cd7dbd95736c5e5d6b912e2caf8ee4d..076a849f60beaf59ffbb365601457b5a45695236 100644 --- a/src/mol-math/geometry/spacegroup/construction.ts +++ b/src/mol-math/geometry/spacegroup/construction.ts @@ -90,7 +90,7 @@ namespace Spacegroup { export function getSymmetryOperator(spacegroup: Spacegroup, index: number, i: number, j: number, k: number): SymmetryOperator { const operator = updateOperatorMatrix(spacegroup, index, i, j, k, Mat4.zero()); - return SymmetryOperator.create(`${index + 1}_${5 + i}${5 + j}${5 + k}`, operator, Vec3.create(i, j, k)); + return SymmetryOperator.create(`${index + 1}_${5 + i}${5 + j}${5 + k}`, operator, { id: '', operList: [] }, Vec3.create(i, j, k)); } function getOperatorMatrix(ids: number[]) { diff --git a/src/mol-math/geometry/symmetry-operator.ts b/src/mol-math/geometry/symmetry-operator.ts index aa703b8be7fbb63321286a33ce8f25119bbbfd12..0c8297c8cef93c0b65b02e8fc67ba6db18ec3cd3 100644 --- a/src/mol-math/geometry/symmetry-operator.ts +++ b/src/mol-math/geometry/symmetry-operator.ts @@ -8,6 +8,14 @@ import { Vec3, Mat4, Mat3 } from '../linear-algebra/3d' interface SymmetryOperator { readonly name: string, + + readonly assembly: { + /** pointer to `pdbx_struct_assembly.id` */ + readonly id: string + /** pointers to `pdbx_struct_oper_list_id` */ + readonly operList: string[] + } + readonly hkl: Vec3, readonly matrix: Mat4, @@ -19,15 +27,15 @@ interface SymmetryOperator { namespace SymmetryOperator { export const DefaultName = '1_555' - export const Default: SymmetryOperator = create(DefaultName, Mat4.identity()); + export const Default: SymmetryOperator = create(DefaultName, Mat4.identity(), { id: '', operList: [] }); const RotationEpsilon = 0.0001; - export function create(name: string, matrix: Mat4, hkl?: Vec3): SymmetryOperator { + export function create(name: string, matrix: Mat4, assembly: SymmetryOperator['assembly'], hkl?: Vec3): SymmetryOperator { const _hkl = hkl ? Vec3.clone(hkl) : Vec3.zero(); - if (Mat4.isIdentity(matrix)) return { name, matrix, inverse: Mat4.identity(), isIdentity: true, hkl: _hkl }; + if (Mat4.isIdentity(matrix)) return { name, assembly, matrix, inverse: Mat4.identity(), isIdentity: true, hkl: _hkl }; if (!Mat4.isRotationAndTranslation(matrix, RotationEpsilon)) throw new Error(`Symmetry operator (${name}) must be a composition of rotation and translation.`); - return { name, matrix, inverse: Mat4.invert(Mat4.zero(), matrix), isIdentity: false, hkl: _hkl }; + return { name, assembly, matrix, inverse: Mat4.invert(Mat4.zero(), matrix), isIdentity: false, hkl: _hkl }; } export function checkIfRotationAndTranslation(rot: Mat3, offset: Vec3) { @@ -49,13 +57,16 @@ namespace SymmetryOperator { } } Mat4.setTranslation(t, offset); - return create(name, t); + return create(name, t, { id: '', operList: [] }); } - /** Apply the 1st and then 2nd operator. ( = second.matrix * first.matrix). */ + /** + * Apply the 1st and then 2nd operator. ( = second.matrix * first.matrix). + * Keep `name`, `assembly` and `hkl` properties from second. + */ export function compose(first: SymmetryOperator, second: SymmetryOperator) { const matrix = Mat4.mul(Mat4.zero(), second.matrix, first.matrix); - return create(second.name, matrix, second.hkl); + return create(second.name, matrix, second.assembly, second.hkl); } export interface CoordinateMapper<T extends number> { (index: T, slot: Vec3): Vec3 } diff --git a/src/mol-model-props/rcsb/assembly-symmetry.ts b/src/mol-model-props/rcsb/assembly-symmetry.ts index 47d2849d74b1ec7cd9482a26785c794d63956573..8a97e66160bdd601f3b067082e91edce2c8337a5 100644 --- a/src/mol-model-props/rcsb/assembly-symmetry.ts +++ b/src/mol-model-props/rcsb/assembly-symmetry.ts @@ -42,6 +42,7 @@ function createDatabaseFromJson(assemblies: ReadonlyArray<AssemblySymmetryGraphQ const axisRows: Table.Row<typeof Schema.rcsb_assembly_symmetry_axis>[] = [] let id = 1 // start feature ids at 1 + let clusterCount = 0 for (let i = 0, il = assemblies.length; i < il; ++i) { const { pdbx_struct_assembly, rcsb_struct_symmetry, rcsb_struct_symmetry_provenance } = assemblies[i] if (!pdbx_struct_assembly || !rcsb_struct_symmetry ||!rcsb_struct_symmetry_provenance) continue @@ -63,20 +64,22 @@ function createDatabaseFromJson(assemblies: ReadonlyArray<AssemblySymmetryGraphQ if (clusters) { for (let k = 0, kl = clusters.length; k < kl; ++k) { const c = clusters[k]! // TODO upstream, array members should not be nullable + const cluster_id = clusterCount + k clusterRows.push({ - id: k, + id: cluster_id, symmetry_id: id, avg_rmsd: c.avg_rmsd || 0, // TODO upstream, should not be nullable, or??? }) for (let l = 0, ll = c.members.length; l < ll; ++l) { const m = c.members[l]! // TODO upstream, array members should not be nullable clusterMemberRows.push({ - cluster_id: k, + cluster_id: cluster_id, asym_id: m.asym_id, pdbx_struct_oper_list_ids: (m.pdbx_struct_oper_list_ids || []) as string[] }) } } + clusterCount += clusters.length } const axes = rss.rotation_axes @@ -156,7 +159,7 @@ const _Descriptor: ModelPropertyDescriptor = { export interface AssemblySymmetry { '@type': 'rcsb_assembly_symmetry', db: AssemblySymmetry.Database - getSymmetries(assemblyId: string): Table<AssemblySymmetry.Schema['rcsb_assembly_symmetry']> + getSymmetries(assemblyIds: string[]): Table<AssemblySymmetry.Schema['rcsb_assembly_symmetry']> getClusters(symmetryId: number): Table<AssemblySymmetry.Schema['rcsb_assembly_symmetry_cluster']> getClusterMembers(clusterId: number): Table<AssemblySymmetry.Schema['rcsb_assembly_symmetry_cluster_member']> getAxes(symmetryId: number): Table<AssemblySymmetry.Schema['rcsb_assembly_symmetry_axis']> @@ -171,10 +174,10 @@ export function AssemblySymmetry(db: AssemblySymmetry.Database): AssemblySymmetr return { '@type': 'rcsb_assembly_symmetry', db, - getSymmetries: (assemblyId: string) => Table.pick(f, f._schema, i => f.assembly_id.value(i) === assemblyId), + getSymmetries: (assemblyIds: string[]) => Table.pick(f, f._schema, i => assemblyIds.includes(f.assembly_id.value(i))), getClusters: (symmetryId: number) => Table.pick(c, c._schema, i => c.symmetry_id.value(i) === symmetryId), getClusterMembers: (clusterId: number) => Table.pick(cm, cm._schema, i => cm.cluster_id.value(i) === clusterId), - getAxes: (symmetryId: number) => Table.pick(a, a._schema, i => a.symmetry_id.value(i) === symmetryId) + getAxes: (symmetryId: number) => Table.pick(a, a._schema, i => a.symmetry_id.value(i) === symmetryId), } } diff --git a/src/mol-model-props/rcsb/representations/assembly-symmetry-axes.ts b/src/mol-model-props/rcsb/representations/assembly-symmetry-axes.ts index dce096fb50cc0df3c91952baefd27dd6336844df..4c4d26bc4fb3b40b4cb9fca4e4da345c5775ec64 100644 --- a/src/mol-model-props/rcsb/representations/assembly-symmetry-axes.ts +++ b/src/mol-model-props/rcsb/representations/assembly-symmetry-axes.ts @@ -23,36 +23,45 @@ import { LocationIterator } from 'mol-geo/util/location-iterator'; import { NullLocation } from 'mol-model/location'; import { PickingId } from 'mol-geo/geometry/picking'; import { OrderedSet, Interval } from 'mol-data/int'; +import { getSymmetrySelectParam, getAssemblyIds } from '../util'; export const AssemblySymmetryAxesParams = { ...ComplexMeshParams, sizeFactor: PD.Numeric(0.4, { min: 0, max: 3, step: 0.01 }), radialSegments: PD.Numeric(16, { min: 3, max: 56, step: 1 }), detail: PD.Numeric(0, { min: 0, max: 3, step: 1 }), - symmetryId: PD.Select<number>(-1, []), + symmetryId: getSymmetrySelectParam(), } export type AssemblySymmetryAxesParams = typeof AssemblySymmetryAxesParams export function getAssemblySymmetryAxesParams(ctx: ThemeRegistryContext, structure: Structure) { const params = PD.clone(AssemblySymmetryAxesParams) - - if (structure.models[0].customProperties.has(AssemblySymmetry.Descriptor)) { - const assemblySymmetry = AssemblySymmetry.get(structure.models[0])! - const assemblyName = structure.assemblyName - const s = assemblySymmetry.db.rcsb_assembly_symmetry - if (s._rowCount) { - params.symmetryId.options = [] - for (let i = 0, il = s._rowCount; i < il; ++i) { - if (s.assembly_id.value(i) === assemblyName) { - params.symmetryId.options.push([ - s.id.value(i), `${s.symbol.value(i)} ${s.kind.value(i)}` - ]) - } - } - params.symmetryId.defaultValue = params.symmetryId.options[0][0] - } - } - + params.symmetryId = getSymmetrySelectParam(structure) return params + + // const params = PD.clone(AssemblySymmetryAxesParams) + + // if (structure.models[0].customProperties.has(AssemblySymmetry.Descriptor)) { + // const assemblySymmetry = AssemblySymmetry.get(structure.models[0])! + // const assemblyName = structure.assemblyName + // const s = assemblySymmetry.db.rcsb_assembly_symmetry + // if (s._rowCount) { + // params.symmetryId.options = [] + // for (let i = 0, il = s._rowCount; i < il; ++i) { + // if (s.assembly_id.value(i) === assemblyName) { + // params.symmetryId.options.push([ + // s.id.value(i), `${s.symbol.value(i)} ${s.kind.value(i)}` + // ]) + // } + // } + // if (options.length) { + // params.symmetryId.options = options + // params.symmetryId.defaultValue = options[0][0] + // } + // params.symmetryId.defaultValue = params.symmetryId.options[0][0] + // } + // } + + // return params } export type AssemblySymmetryAxesRepresentation = StructureRepresentation<AssemblySymmetryAxesParams> @@ -126,13 +135,11 @@ export function createAssemblySymmetryAxesMesh(ctx: VisualContext, structure: St const symmetry = Table.pickRow(s, i => s.id.value(i) === symmetryId) if (!symmetry) return Mesh.createEmpty(mesh) - // symmetry.assembly_id not available for structure.assemblyName - if (symmetry.assembly_id !== structure.assemblyName) return Mesh.createEmpty(mesh) + // check if structure.units operators have symmetry.assembly_id + if (!getAssemblyIds(structure.units).includes(symmetry.assembly_id)) return Mesh.createEmpty(mesh) const axes = assemblySymmetry.db.rcsb_assembly_symmetry_axis const vectorSpace = AssemblySymmetry.Schema.rcsb_assembly_symmetry_axis.start.space; - // const colors: Color[] = [] - // const labels: string[] = [] const radius = 1 * sizeFactor const cylinderProps = { radiusTop: radius, radiusBottom: radius } @@ -147,8 +154,6 @@ export function createAssemblySymmetryAxesMesh(ctx: VisualContext, structure: St addSphere(builderState, start, radius, 2) addSphere(builderState, end, radius, 2) addCylinder(builderState, start, end, 1, cylinderProps) - // colors.push(Color(0xCCEE11)) - // labels.push(`Axis ${i + 1} for ${symmetry.kind} ${symmetry.type.toLowerCase()} symmetry`) } return MeshBuilder.getMesh(builderState) } \ No newline at end of file diff --git a/src/mol-model-props/rcsb/themes/assembly-symmetry-cluster.ts b/src/mol-model-props/rcsb/themes/assembly-symmetry-cluster.ts index d739f926c065dc8969bd1833f4e696d45de133af..efe1bb6fba7c3b5ab1453c7080ec3cb4c2f036b7 100644 --- a/src/mol-model-props/rcsb/themes/assembly-symmetry-cluster.ts +++ b/src/mol-model-props/rcsb/themes/assembly-symmetry-cluster.ts @@ -13,6 +13,7 @@ import { ColorScale, Color } from 'mol-util/color'; import { Unit, StructureElement, StructureProperties } from 'mol-model/structure'; import { Location } from 'mol-model/location'; import { ColorListName, ColorListOptions } from 'mol-util/color/scale'; +import { getSymmetrySelectParam } from '../util'; const DefaultColor = Color(0xCCCCCC) @@ -26,35 +27,18 @@ function getAsymId(unit: Unit): StructureElement.Property<string> { } } -function clusterMemberKey (asym_id: string, oper_list_ids: string[]) { - return `${asym_id}-${oper_list_ids.join('x')}` +function clusterMemberKey(assemblyId: string, asymId: string, operList: string[]) { + return `${assemblyId}-${asymId}-${operList.join('|')}` } export const AssemblySymmetryClusterColorThemeParams = { list: PD.Select<ColorListName>('Viridis', ColorListOptions), - symmetryId: PD.Select<number>(-1, []), + symmetryId: getSymmetrySelectParam(), } export type AssemblySymmetryClusterColorThemeParams = typeof AssemblySymmetryClusterColorThemeParams export function getAssemblySymmetryClusterColorThemeParams(ctx: ThemeDataContext) { const params = PD.clone(AssemblySymmetryClusterColorThemeParams) - - if (ctx.structure && ctx.structure.models[0].customProperties.has(AssemblySymmetry.Descriptor)) { - const assemblySymmetry = AssemblySymmetry.get(ctx.structure.models[0])! - const assemblyName = ctx.structure.assemblyName - const s = assemblySymmetry.db.rcsb_assembly_symmetry - if (s._rowCount) { - params.symmetryId.options = [] - for (let i = 0, il = s._rowCount; i < il; ++i) { - if (s.assembly_id.value(i) === assemblyName) { - params.symmetryId.options.push([ - s.id.value(i), `${s.symbol.value(i)} ${s.kind.value(i)}` - ]) - } - } - params.symmetryId.defaultValue = params.symmetryId.options[0][0] - } - } - + params.symmetryId = getSymmetrySelectParam(ctx.structure) return params } @@ -77,10 +61,10 @@ export function AssemblySymmetryClusterColorTheme(ctx: ThemeDataContext, props: for (let i = 0, il = clusters._rowCount; i < il; ++i) { const clusterMembers = assemblySymmetry.getClusterMembers(clusters.id.value(i)) for (let j = 0, jl = clusterMembers._rowCount; j < jl; ++j) { - const asym_id = clusterMembers.asym_id.value(j) - const oper_list_ids = clusterMembers.pdbx_struct_oper_list_ids.value(j) - if (oper_list_ids.length === 0) oper_list_ids.push('1') // TODO hack assuming '1' is the id of the identity operator - clusterByMember.set(clusterMemberKey(asym_id, oper_list_ids), i) + const asymId = clusterMembers.asym_id.value(j) + const operList = clusterMembers.pdbx_struct_oper_list_ids.value(j) + if (operList.length === 0) operList.push('1') // TODO hack assuming '1' is the id of the identity operator + clusterByMember.set(clusterMemberKey(symmetry.assembly_id, asymId, operList), i) } } @@ -88,11 +72,12 @@ export function AssemblySymmetryClusterColorTheme(ctx: ThemeDataContext, props: color = (location: Location): Color => { if (StructureElement.isLocation(location)) { - const asym_id = getAsymId(location.unit) - const ns = location.unit.conformation.operator.name.split('-') - const oper_list_ids = ns.length === 2 ? ns[1].split('x') : [] - const cluster = clusterByMember.get(clusterMemberKey(asym_id(location), oper_list_ids)) - return cluster !== undefined ? scale.color(cluster) : DefaultColor + const { assembly } = location.unit.conformation.operator + if (assembly && assembly.id === symmetry.assembly_id) { + const asymId = getAsymId(location.unit)(location) + const cluster = clusterByMember.get(clusterMemberKey(assembly.id, asymId, assembly.operList)) + return cluster !== undefined ? scale.color(cluster) : DefaultColor + } } return DefaultColor } diff --git a/src/mol-model-props/rcsb/util.ts b/src/mol-model-props/rcsb/util.ts new file mode 100644 index 0000000000000000000000000000000000000000..f555295a17d5dba9c31a2d971cb98191b57b6ede --- /dev/null +++ b/src/mol-model-props/rcsb/util.ts @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { Unit, Structure } from 'mol-model/structure'; +import { ParamDefinition as PD } from 'mol-util/param-definition' +import { AssemblySymmetry } from './assembly-symmetry'; + +export function getAssemblyIds(units: ReadonlyArray<Unit>) { + const ids = new Set<string>() + units.forEach(u => { + if (u.conformation.operator.assembly) ids.add(u.conformation.operator.assembly.id) + }) + return Array.from(ids) +} + +export function getSymmetrySelectParam(structure?: Structure) { + const param = PD.Select<number>(-1, [[-1, 'No Symmetries']]) + if (structure && structure.models[0].customProperties.has(AssemblySymmetry.Descriptor)) { + const assemblySymmetry = AssemblySymmetry.get(structure.models[0])! + const assemblyIds = getAssemblyIds(structure.units) + const s = assemblySymmetry.getSymmetries(assemblyIds) + if (s._rowCount) { + const options: [number, string][] = [] + for (let i = 0, il = s._rowCount; i < il; ++i) { + options.push([ s.id.value(i), `${s.assembly_id.value(i)}: ${s.symbol.value(i)} ${s.kind.value(i)}` ]) + } + if (options.length) { + param.options = options + param.defaultValue = options[0][0] + } + } + } + return param +} \ No newline at end of file diff --git a/src/mol-model/structure/model/formats/mmcif/assembly.ts b/src/mol-model/structure/model/formats/mmcif/assembly.ts index 6816c0282e4ea0e995fbd8af2eb19c5392bcf4eb..d0c9eddeac44e99333be0e4f0b77c14d189cfe56 100644 --- a/src/mol-model/structure/model/formats/mmcif/assembly.ts +++ b/src/mol-model/structure/model/formats/mmcif/assembly.ts @@ -26,7 +26,7 @@ export function createAssemblies(format: mmCIF_Format): ReadonlyArray<Assembly> } type Matrices = Map<string, Mat4> -type Generator = { expression: string, asymIds: string[] } +type Generator = { assemblyId: string, expression: string, asymIds: string[] } function createAssembly(format: mmCIF_Format, index: number, matrices: Matrices): Assembly { const { pdbx_struct_assembly, pdbx_struct_assembly_gen } = format.data; @@ -40,6 +40,7 @@ function createAssembly(format: mmCIF_Format, index: number, matrices: Matrices) for (let i = 0, _i = pdbx_struct_assembly_gen._rowCount; i < _i; i++) { if (assembly_id.value(i) !== id) continue; generators[generators.length] = { + assemblyId: id, expression: oper_expression.value(i), asymIds: asym_id_list.value(i) }; @@ -57,7 +58,7 @@ function operatorGroupsProvider(generators: Generator[], matrices: Matrices): () const gen = generators[i]; const operatorList = parseOperatorList(gen.expression); const operatorNames = expandOperators(operatorList); - const operators = getAssemblyOperators(matrices, operatorNames, operatorOffset); + const operators = getAssemblyOperators(matrices, operatorNames, operatorOffset, gen.assemblyId); const selector = Q.generators.atoms({ chainTest: Q.pred.and( Q.pred.eq(ctx => StructureProperties.unit.operator_name(ctx.element), SymmetryOperator.DefaultName), Q.pred.inSet(ctx => StructureProperties.chain.label_asym_id(ctx.element), gen.asymIds) @@ -107,18 +108,17 @@ function expandOperators1(operatorNames: string[][], list: string[][], i: number } } -function getAssemblyOperators(matrices: Matrices, operatorNames: string[][], startIndex: number) { +function getAssemblyOperators(matrices: Matrices, operatorNames: string[][], startIndex: number, assemblyId: string) { const operators: SymmetryOperator[] = []; + let index = startIndex; for (let op of operatorNames) { let m = Mat4.identity(); for (let i = 0; i < op.length; i++) { Mat4.mul(m, m, matrices.get(op[i])!); } - // TODO currently using the original operator name for the symmetry operator to be able - // to link it to the original operator but it might be clearer to introduce an extra field??? - // Operator names are joined together by 'x' to indicate matrix multiplication. - operators[operators.length] = SymmetryOperator.create(`A-${op.join('x')}`, m); + index++ + operators[operators.length] = SymmetryOperator.create(`A-${index}`, m, { id: assemblyId, operList: op }); } return operators; diff --git a/src/mol-model/structure/query/queries/generators.ts b/src/mol-model/structure/query/queries/generators.ts index 64c4451e125b0bc9372142b76214bd8557f58a6e..34ce3fd620119edf4ce852b80bd19e146f205489 100644 --- a/src/mol-model/structure/query/queries/generators.ts +++ b/src/mol-model/structure/query/queries/generators.ts @@ -171,7 +171,7 @@ function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, group function getRingStructure(unit: Unit.Atomic, ring: UnitRing) { const elements = new Int32Array(ring.length) as any as ElementIndex[]; for (let i = 0, _i = ring.length; i < _i; i++) elements[i] = unit.elements[ring[i]]; - return Structure.create([unit.getChild(SortedArray.ofSortedArray(elements))], '') + return Structure.create([unit.getChild(SortedArray.ofSortedArray(elements))]) } export function rings(fingerprints?: ArrayLike<UnitRing.Fingerprint>): StructureQuery { diff --git a/src/mol-model/structure/query/queries/internal.ts b/src/mol-model/structure/query/queries/internal.ts index 5188c1397c3d1272d06b1e58c3c071501cd67893..8cf1078110a6c3c929f56bada9d17a1e2ea8d8bf 100644 --- a/src/mol-model/structure/query/queries/internal.ts +++ b/src/mol-model/structure/query/queries/internal.ts @@ -35,7 +35,7 @@ export function atomicSequence(): StructureQuery { units.push(unit); } - return StructureSelection.Singletons(inputStructure, new Structure(units, inputStructure.assemblyName)); + return StructureSelection.Singletons(inputStructure, new Structure(units)); }; } @@ -54,7 +54,7 @@ export function water(): StructureQuery { if (P.entity.type(l) !== 'water') continue; units.push(unit); } - return StructureSelection.Singletons(inputStructure, new Structure(units, inputStructure.assemblyName)); + return StructureSelection.Singletons(inputStructure, new Structure(units)); }; } @@ -84,7 +84,7 @@ export function atomicHet(): StructureQuery { units.push(unit); } - return StructureSelection.Singletons(inputStructure, new Structure(units, inputStructure.assemblyName)); + return StructureSelection.Singletons(inputStructure, new Structure(units)); }; } @@ -97,6 +97,6 @@ export function spheres(): StructureQuery { if (unit.kind !== Unit.Kind.Spheres) continue; units.push(unit); } - return StructureSelection.Singletons(inputStructure, new Structure(units, inputStructure.assemblyName)); + return StructureSelection.Singletons(inputStructure, new Structure(units)); }; } diff --git a/src/mol-model/structure/query/selection.ts b/src/mol-model/structure/query/selection.ts index 69aba9fa26d271667a1f485b2e3d547e67d43ae1..b257170712dc78158da19a0787c0f4718a8a615f 100644 --- a/src/mol-model/structure/query/selection.ts +++ b/src/mol-model/structure/query/selection.ts @@ -109,7 +109,7 @@ namespace StructureSelection { const { elements } = unit; for (let i = 0, _i = elements.length; i < _i; i++) { // TODO: optimize this somehow??? - const s = Structure.create([unit.getChild(SortedArray.ofSingleton(elements[i]))], sel.structure.assemblyName); + const s = Structure.create([unit.getChild(SortedArray.ofSingleton(elements[i]))]); fn(s, idx++); } } diff --git a/src/mol-model/structure/query/utils/structure-set.ts b/src/mol-model/structure/query/utils/structure-set.ts index 46a5c0f43aeb2dfa57e30d6b35e240e34e83528b..85867419505a8e3494e2f7a9e70838f140c0a00c 100644 --- a/src/mol-model/structure/query/utils/structure-set.ts +++ b/src/mol-model/structure/query/utils/structure-set.ts @@ -80,7 +80,7 @@ export function structureIntersect(sA: Structure, sB: Structure): Structure { } } - return Structure.create(units, sA.assemblyName === sB.assemblyName ? sA.assemblyName : ''); + return Structure.create(units); } export function structureSubtract(a: Structure, b: Structure): Structure { @@ -100,5 +100,5 @@ export function structureSubtract(a: Structure, b: Structure): Structure { } } - return Structure.create(units, a.assemblyName === b.assemblyName ? a.assemblyName : ''); + return Structure.create(units); } \ No newline at end of file diff --git a/src/mol-model/structure/structure/structure.ts b/src/mol-model/structure/structure/structure.ts index a61046ff27bd68452ccdf371f599046897d73b6a..d7b99e9ff018db30162d37aae9a615c2892c2e20 100644 --- a/src/mol-model/structure/structure/structure.ts +++ b/src/mol-model/structure/structure/structure.ts @@ -49,8 +49,7 @@ class Structure { transformHash: number, elementCount: number, polymerResidueCount: number, - assemblyName: string - } = { hashCode: -1, transformHash: -1, elementCount: 0, polymerResidueCount: 0, assemblyName: '' }; + } = { hashCode: -1, transformHash: -1, elementCount: 0, polymerResidueCount: 0 }; subsetBuilder(isSorted: boolean) { return new StructureSubsetBuilder(this, isSorted); @@ -66,11 +65,6 @@ class Structure { return this._props.polymerResidueCount; } - /** Name of the assembly given by `_pdbx_struct_assembly.id` when applicable */ - get assemblyName() { - return this._props.assemblyName; - } - /** Coarse structure, defined as Containing less than twice as many elements as polymer residues */ get isCoarse() { const ec = this.elementCount @@ -176,7 +170,7 @@ class Structure { return SortedArray.has(this.unitMap.get(e.unit.id).elements, e.element); } - constructor(units: ArrayLike<Unit>, assemblyName: string) { + constructor(units: ArrayLike<Unit>) { const map = IntMap.Mutable<Unit>(); let elementCount = 0; let polymerResidueCount = 0; @@ -195,7 +189,6 @@ class Structure { this.units = units as ReadonlyArray<Unit>; this._props.elementCount = elementCount; this._props.polymerResidueCount = polymerResidueCount; - this._props.assemblyName = assemblyName } } @@ -286,7 +279,7 @@ function getUniqueAtomicResidueIndices(structure: Structure): ReadonlyMap<UUID, } namespace Structure { - export const Empty = new Structure([], ''); + export const Empty = new Structure([]); /** Represents a single structure */ export interface Loci { @@ -305,7 +298,7 @@ namespace Structure { return a.structure === b.structure } - export function create(units: ReadonlyArray<Unit>, assemblyName: string): Structure { return new Structure(units, assemblyName); } + export function create(units: ReadonlyArray<Unit>): Structure { return new Structure(units); } /** * Construct a Structure from a model. @@ -346,7 +339,7 @@ namespace Structure { } } - return builder.getStructure('deposited'); + return builder.getStructure(); } function isWaterChain(model: Model, chainIndex: ChainIndex, indices: SortedArray) { @@ -384,11 +377,11 @@ namespace Structure { const units: Unit[] = []; for (const u of s.units) { const old = u.conformation.operator; - const op = SymmetryOperator.create(old.name, transform, old.hkl); + const op = SymmetryOperator.create(old.name, transform, { id: '', operList: [] }, old.hkl); units.push(u.applyOperator(u.id, op)); } - return new Structure(units, s.assemblyName); + return new Structure(units); } export class StructureBuilder { @@ -407,8 +400,8 @@ namespace Structure { return newUnit; } - getStructure(assemblyName: string): Structure { - return create(this.units, assemblyName); + getStructure(): Structure { + return create(this.units); } get isEmpty() { diff --git a/src/mol-model/structure/structure/symmetry.ts b/src/mol-model/structure/structure/symmetry.ts index 2acbf7d87ff2c96e0fa81f5c466d885e4ce1d050..5af14696a9e1b5017299ace7cbe5643956a2bc1f 100644 --- a/src/mol-model/structure/structure/symmetry.ts +++ b/src/mol-model/structure/structure/symmetry.ts @@ -42,7 +42,7 @@ namespace StructureSymmetry { } } - return assembler.getStructure(asmName); + return assembler.getStructure(); }); } @@ -118,7 +118,7 @@ function assembleOperators(structure: Structure, operators: ReadonlyArray<Symmet assembler.addWithOperator(unit, oper); } } - return assembler.getStructure(structure.assemblyName); + return assembler.getStructure(); } async function _buildNCS(ctx: RuntimeContext, structure: Structure) { @@ -173,7 +173,7 @@ async function findMatesRadius(ctx: RuntimeContext, structure: Structure, radius } - return assembler.getStructure(structure.assemblyName); + return assembler.getStructure(); } export default StructureSymmetry; \ No newline at end of file diff --git a/src/mol-model/structure/structure/util/subset-builder.ts b/src/mol-model/structure/structure/util/subset-builder.ts index 608bae0de74bdb702773f6b24f77d516ecdfe5f1..77c228902fc14c27a75e070df1868498ca68057a 100644 --- a/src/mol-model/structure/structure/util/subset-builder.ts +++ b/src/mol-model/structure/structure/util/subset-builder.ts @@ -90,7 +90,7 @@ export class StructureSubsetBuilder { newUnits[newUnits.length] = child; } - return Structure.create(newUnits, this.parent.assemblyName); + return Structure.create(newUnits); } getStructure() { diff --git a/src/mol-model/structure/structure/util/unique-subset-builder.ts b/src/mol-model/structure/structure/util/unique-subset-builder.ts index f19ecace755931cd759e6c12e62a992a872fa59b..bc18e6519217570f2bb6e6b8097e5baa3e2d6f96 100644 --- a/src/mol-model/structure/structure/util/unique-subset-builder.ts +++ b/src/mol-model/structure/structure/util/unique-subset-builder.ts @@ -85,7 +85,7 @@ export class StructureUniqueSubsetBuilder { newUnits[newUnits.length] = child; } - return Structure.create(newUnits, this.parent.assemblyName); + return Structure.create(newUnits); } get isEmpty() {