Browse Source

wip, pair-restraints

Alexander Rose 6 years ago
parent
commit
b1296fb983

+ 5 - 10
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

+ 2 - 2
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>,

+ 2 - 1
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'

+ 38 - 22
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 }
+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'
+}

+ 7 - 7
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 };

+ 7 - 0
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`

+ 7 - 3
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 })