diff --git a/src/mol-geo/representation/structure/visual/cross-link-restraint-cylinder.ts b/src/mol-geo/representation/structure/visual/cross-link-restraint-cylinder.ts index 6930ff97c4226f37b297e587406ede6f383f3b76..de81e58df39a4d2da5573d99895442b6b651fbca 100644 --- a/src/mol-geo/representation/structure/visual/cross-link-restraint-cylinder.ts +++ b/src/mol-geo/representation/structure/visual/cross-link-restraint-cylinder.ts @@ -29,15 +29,15 @@ async function createCrossLinkRestraintCylinderMesh(ctx: RuntimeContext, structu const builderProps = { linkCount: crossLinks.count, - referencePosition: (edgeIndex: number) => null, + referencePosition: () => null, position: (posA: Vec3, posB: Vec3, edgeIndex: number) => { const b = crossLinks.pairs[edgeIndex] const uA = b.unitA, uB = b.unitB uA.conformation.position(uA.elements[b.indexA], posA) uB.conformation.position(uB.elements[b.indexB], posB) }, - order: (edgeIndex: number) => 1, - flags: (edgeIndex: number) => BitFlags.create(LinkType.Flag.None), + order: () => 1, + flags: () => BitFlags.create(LinkType.Flag.None), radius: (edgeIndex: number) => { const b = crossLinks.pairs[edgeIndex] location.unit = b.unitA @@ -76,7 +76,7 @@ function CrossLinkRestraintIterator(structure: Structure): LocationIterator { const elementCount = pairs.length const instanceCount = 1 const location = Link.Location() - const getLocation = (elementIndex: number, instanceIndex: number) => { + const getLocation = (elementIndex: number) => { const pair = pairs[elementIndex] location.aUnit = pair.unitA location.aIndex = pair.indexA @@ -92,12 +92,7 @@ function getLinkLoci(pickingId: PickingId, structure: Structure, id: number) { if (id === objectId) { const pair = structure.crossLinkRestraints.pairs[elementId] if (pair) { - return Link.Loci([ - Link.Location( - pair.unitA, pair.indexA as StructureElement.UnitIndex, - pair.unitB, pair.indexB as StructureElement.UnitIndex - ) - ]) + return Link.Loci([ Link.Location(pair.unitA, pair.indexA, pair.unitB, pair.indexB) ]) } } return EmptyLoci diff --git a/src/mol-model/structure/structure/structure.ts b/src/mol-model/structure/structure/structure.ts index 233d73f9821d364a742c10199e5c3240ee22c036..edc6447f0a1447cd06ccd8f4a0e7a4870468f926 100644 --- a/src/mol-model/structure/structure/structure.ts +++ b/src/mol-model/structure/structure/structure.ts @@ -15,7 +15,7 @@ import { StructureLookup3D } from './util/lookup3d'; import { CoarseElements } from '../model/properties/coarse'; import { StructureSubsetBuilder } from './util/subset-builder'; import { InterUnitBonds, computeInterUnitBonds } from './unit/links'; -import { CrossLinkRestraints, extractCrossLinkRestraints } from './unit/pair-restraints'; +import { PairRestraints, CrossLinkRestraint, extractCrossLinkRestraints } from './unit/pair-restraints'; import StructureSymmetry from './symmetry'; import StructureProperties from './properties'; import { ResidueIndex } from '../model/indexing'; @@ -29,7 +29,7 @@ class Structure { private _props: { lookup3d?: StructureLookup3D, links?: InterUnitBonds, - crossLinkRestraints?: CrossLinkRestraints, + crossLinkRestraints?: PairRestraints<CrossLinkRestraint>, unitSymmetryGroups?: ReadonlyArray<Unit.SymmetryGroup>, carbohydrates?: Carbohydrates, models?: ReadonlyArray<Model>, diff --git a/src/mol-model/structure/structure/unit/pair-restraints.ts b/src/mol-model/structure/structure/unit/pair-restraints.ts index 6d0d0bd78e446cc9141a4f4b20b2cc8d61332f68..890fb6b03666a40e5157d80430f0b098d2db98ad 100644 --- a/src/mol-model/structure/structure/unit/pair-restraints.ts +++ b/src/mol-model/structure/structure/unit/pair-restraints.ts @@ -6,4 +6,5 @@ export * from './pair-restraints/data' export * from './pair-restraints/extract-cross-links' -// export * from './pair-restraints/extract-predicted_contacts' +// export * from './pair-restraints/extract-predicted-contacts' +// export * from './pair-restraints/extract-distance-restraints' diff --git a/src/mol-model/structure/structure/unit/pair-restraints/data.ts b/src/mol-model/structure/structure/unit/pair-restraints/data.ts index 7b0d01e86e2d65de009fe9ed27be05ba197cb04c..f402aab8e991b6fbc7a03e4bdc4fb38fbb9ef622 100644 --- a/src/mol-model/structure/structure/unit/pair-restraints/data.ts +++ b/src/mol-model/structure/structure/unit/pair-restraints/data.ts @@ -9,26 +9,37 @@ import { StructureElement } from '../../../structure'; const emptyArray: number[] = [] -class CrossLinkRestraints { +interface PairRestraint { + readonly unitA: Unit, + readonly unitB: Unit, + readonly indexA: StructureElement.UnitIndex, + readonly indexB: StructureElement.UnitIndex, +} + +function getPairKey(indexA: StructureElement.UnitIndex, unitA: Unit, indexB: StructureElement.UnitIndex, unitB: Unit) { + return `${indexA}|${unitA.id}|${indexB}|${unitB.id}` +} + +export class PairRestraints<T extends PairRestraint> { readonly count: number private readonly pairKeyIndices: Map<string, number[]> /** Indices into this.pairs */ getPairIndices(indexA: StructureElement.UnitIndex, unitA: Unit, indexB: StructureElement.UnitIndex, unitB: Unit): ReadonlyArray<number> { - const key = CrossLinkRestraints.getPairKey(indexA, unitA, indexB, unitB) + const key = getPairKey(indexA, unitA, indexB, unitB) const indices = this.pairKeyIndices.get(key) return indices !== undefined ? indices : emptyArray } - getPairs(indexA: StructureElement.UnitIndex, unitA: Unit, indexB: StructureElement.UnitIndex, unitB: Unit): CrossLinkRestraints.Pair[] | undefined { + getPairs(indexA: StructureElement.UnitIndex, unitA: Unit, indexB: StructureElement.UnitIndex, unitB: Unit): T[] | undefined { const indices = this.getPairIndices(indexA, unitA, indexB, unitB) return indices.length ? indices.map(idx => this.pairs[idx]) : undefined } - constructor(public pairs: ReadonlyArray<CrossLinkRestraints.Pair>) { + constructor(public pairs: ReadonlyArray<T>) { const pairKeyIndices = new Map<string, number[]>() this.pairs.forEach((p, i) => { - const key = CrossLinkRestraints.getPairKey(p.indexA, p.unitA, p.indexB, p.unitB) + const key = getPairKey(p.indexA, p.unitA, p.indexB, p.unitB) const indices = pairKeyIndices.get(key) if (indices) indices.push(i) else pairKeyIndices.set(key, [i]) @@ -39,23 +50,28 @@ class CrossLinkRestraints { } } -namespace CrossLinkRestraints { - export interface Pair { - readonly unitA: Unit, - readonly unitB: Unit, - readonly indexA: StructureElement.UnitIndex, - readonly indexB: StructureElement.UnitIndex, - - readonly restraintType: 'harmonic' | 'upper bound' | 'lower bound', - readonly distanceThreshold: number, - readonly psi: number, - readonly sigma1: number, - readonly sigma2: number, - } +export interface CrossLinkRestraint extends PairRestraint { + readonly restraintType: 'harmonic' | 'upper bound' | 'lower bound' + readonly distanceThreshold: number + readonly psi: number + readonly sigma1: number + readonly sigma2: number +} - export function getPairKey(indexA: StructureElement.UnitIndex, unitA: Unit, indexB: StructureElement.UnitIndex, unitB: Unit) { - return `${indexA}|${unitA.id}|${indexB}|${unitB.id}` - } +export interface PredictedContactRestraint extends PairRestraint { + readonly distance_lower_limit: number + readonly distance_upper_limit: number + readonly probability: number + readonly restraint_type: 'lower bound' | 'upper bound' | 'lower and upper bound' + readonly model_granularity: 'by-residue' | 'by-feature' | 'by-atom' } -export { CrossLinkRestraints } \ No newline at end of file +export interface DistanceRestraint extends PairRestraint { + readonly upper_limit: number + readonly upper_limit_esd: number + readonly lower_limit: number + readonly lower_limit_esd: number + readonly probability: number + readonly restraint_type: 'lower bound' | 'upper bound' | 'lower and upper bound' + readonly granularity: 'by-residue' | 'by-atom' +} \ No newline at end of file diff --git a/src/mol-model/structure/structure/unit/pair-restraints/extract-cross-links.ts b/src/mol-model/structure/structure/unit/pair-restraints/extract-cross-links.ts index cfe6aaa2326f812e380adcea1b1add4a10dd8645..28ae9d1be1bb2d38ac20cd7a50206415f6acfd88 100644 --- a/src/mol-model/structure/structure/unit/pair-restraints/extract-cross-links.ts +++ b/src/mol-model/structure/structure/unit/pair-restraints/extract-cross-links.ts @@ -7,7 +7,7 @@ import Unit from '../../unit'; import Structure from '../../structure'; import { IHMCrossLinkRestraint } from '../../../model/formats/mmcif/pair-restraint'; -import { CrossLinkRestraints } from './data'; +import { PairRestraints, CrossLinkRestraint } from './data'; import { StructureElement } from '../../../structure'; function _addRestraints(map: Map<number, number>, unit: Unit, restraints: IHMCrossLinkRestraint) { @@ -21,7 +21,7 @@ function _addRestraints(map: Map<number, number>, unit: Unit, restraints: IHMCro } } -function extractInter(pairs: CrossLinkRestraints.Pair[], unitA: Unit, unitB: Unit) { +function extractInter(pairs: CrossLinkRestraint[], unitA: Unit, unitB: Unit) { if (unitA.model !== unitB.model) return if (unitA.model.sourceData.kind !== 'mmCIF') return @@ -44,7 +44,7 @@ function extractInter(pairs: CrossLinkRestraints.Pair[], unitA: Unit, unitB: Uni }) } -function extractIntra(pairs: CrossLinkRestraints.Pair[], unit: Unit) { +function extractIntra(pairs: CrossLinkRestraint[], unit: Unit) { if (unit.model.sourceData.kind !== 'mmCIF') return const restraints = IHMCrossLinkRestraint.fromModel(unit.model) @@ -75,7 +75,7 @@ function extractIntra(pairs: CrossLinkRestraints.Pair[], unit: Unit) { }) } -function createCrossLinkRestraint(unitA: Unit, indexA: StructureElement.UnitIndex, unitB: Unit, indexB: StructureElement.UnitIndex, restraints: IHMCrossLinkRestraint, row: number): CrossLinkRestraints.Pair { +function createCrossLinkRestraint(unitA: Unit, indexA: StructureElement.UnitIndex, unitB: Unit, indexB: StructureElement.UnitIndex, restraints: IHMCrossLinkRestraint, row: number): CrossLinkRestraint { return { unitA, indexA, unitB, indexB, @@ -87,8 +87,8 @@ function createCrossLinkRestraint(unitA: Unit, indexA: StructureElement.UnitInde } } -function extractCrossLinkRestraints(structure: Structure): CrossLinkRestraints { - const pairs: CrossLinkRestraints.Pair[] = [] +function extractCrossLinkRestraints(structure: Structure): PairRestraints<CrossLinkRestraint> { + const pairs: CrossLinkRestraint[] = [] const n = structure.units.length for (let i = 0; i < n; ++i) { @@ -100,7 +100,7 @@ function extractCrossLinkRestraints(structure: Structure): CrossLinkRestraints { } } - return new CrossLinkRestraints(pairs) + return new PairRestraints(pairs) } export { extractCrossLinkRestraints }; diff --git a/src/mol-model/structure/structure/unit/pair-restraints/extract-distance-restraints.ts b/src/mol-model/structure/structure/unit/pair-restraints/extract-distance-restraints.ts new file mode 100644 index 0000000000000000000000000000000000000000..f19797cb6a8dc5eed5dacaaf0201d24d458fba44 --- /dev/null +++ b/src/mol-model/structure/structure/unit/pair-restraints/extract-distance-restraints.ts @@ -0,0 +1,7 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +// TODO extract from `_ma_distance_restraints` \ No newline at end of file diff --git a/src/mol-view/stage.ts b/src/mol-view/stage.ts index 3c21cce9fc41f1f8e750ef17b3ddd154372720a5..e13d439a542d27d850c7b19018d7904924228e36 100644 --- a/src/mol-view/stage.ts +++ b/src/mol-view/stage.ts @@ -30,7 +30,6 @@ const ballAndStickProps: Partial<BallAndStickProps> = { doubleSided: true, colorTheme: { name: 'chain-id' }, sizeTheme: { name: 'uniform', value: 0.15 }, - linkRadius: 0.15, quality: 'auto', useFog: false } @@ -38,7 +37,7 @@ const ballAndStickProps: Partial<BallAndStickProps> = { const distanceRestraintProps: Partial<DistanceRestraintProps> = { doubleSided: true, colorTheme: { name: 'chain-id' }, - linkRadius: 0.5, + sizeTheme: { name: 'uniform', value: 0.6 }, quality: 'auto', useFog: false } @@ -132,11 +131,16 @@ export class Stage { // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000006.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000007.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000008.cif`) // ok + // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000009.cif`) // TODO sequence related error // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000010.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000011.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000012.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000014.cif`) // ok + // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000015.cif`) // TODO sequence related error // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000016.cif`) // ok + // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000017.cif`) // ok + // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000020.cif`) // ok + // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000021.cif`) // ok } async loadMmcifUrl (url: string) { @@ -146,7 +150,7 @@ export class Stage { StructureToBallAndStick.apply(this.ctx, structureEntity, { ...ballAndStickProps, visible: true }) StructureToSpacefill.apply(this.ctx, structureEntity, { ...spacefillProps, visible: false }) - StructureToDistanceRestraint.apply(this.ctx, structureEntity, { ...distanceRestraintProps, visible: false }) + StructureToDistanceRestraint.apply(this.ctx, structureEntity, { ...distanceRestraintProps, visible: true }) StructureToBackbone.apply(this.ctx, structureEntity, { ...backboneProps, visible: false }) StructureToCartoon.apply(this.ctx, structureEntity, { ...cartoonProps, visible: true }) StructureToCarbohydrate.apply(this.ctx, structureEntity, { ...carbohydrateProps, visible: true })