Browse Source

added util methods

Alexander Rose 5 years ago
parent
commit
1f38d48897

+ 113 - 0
src/structure-viewer/helpers/util.ts

@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Model, Structure } from 'molstar/lib/mol-model/structure';
+import { MmcifFormat } from 'molstar/lib/mol-model-formats/structure/mmcif';
+
+export function modelHasSymmetry(model: Model) {
+    if (!MmcifFormat.is(model.sourceData)) return false
+    const { db } = model.sourceData.data
+    return (
+        db.symmetry._rowCount === 1 && db.cell._rowCount === 1 && !(
+            db.symmetry.Int_Tables_number.value(0) === 1 &&
+            db.cell.angle_alpha.value(0) === 90 &&
+            db.cell.angle_beta.value(0) === 90 &&
+            db.cell.angle_gamma.value(0) === 90 &&
+            db.cell.length_a.value(0) === 1 &&
+            db.cell.length_b.value(0) === 1 &&
+            db.cell.length_c.value(0) === 1
+        )
+    )
+}
+
+export function modelFromCrystallography(model: Model) {
+    if (!MmcifFormat.is(model.sourceData)) return false
+    const { db } = model.sourceData.data
+    for (let i = 0; i < db.exptl.method.rowCount; i++) {
+        const v = db.exptl.method.value(i).toUpperCase()
+        if (v.indexOf('DIFFRACTION') >= 0) return true
+    }
+    return false
+}
+
+export function modelFromNmr(model: Model) {
+    if (!MmcifFormat.is(model.sourceData)) return false
+    const { db } = model.sourceData.data
+    for (let i = 0; i < db.exptl.method.rowCount; i++) {
+        const v = db.exptl.method.value(i).toUpperCase()
+        if (v.indexOf('NMR') >= 0) return true
+    }
+    return false
+}
+
+export function modelHasXrayMap(model: Model) {
+    if (!MmcifFormat.is(model.sourceData)) return
+    const { db } = model.sourceData.data
+    return db.pdbx_database_status.status_code_sf.value(0) === 'REL'
+}
+
+export function modelHasEmMap(model: Model) {
+    if (!MmcifFormat.is(model.sourceData)) return
+    const { db } = model.sourceData.data
+    let hasEmMap = false
+    for (let i = 0, il = db.pdbx_database_related._rowCount; i < il; ++i) {
+        if (db.pdbx_database_related.db_name.value(i).toUpperCase() === 'EMDB') {
+            hasEmMap = true
+            break
+        }
+    }
+    return hasEmMap
+}
+
+export function modelHasMap(model: Model) {
+    return modelHasXrayMap(model) || modelHasEmMap(model)
+}
+
+//
+
+function getPolymerSymmetryGroups(structure: Structure) {
+    return structure.unitSymmetryGroups.filter(ug => ug.units[0].polymerElements.length > 0)
+}
+
+/**
+ * Try to match fiber-like structures like 6nk4
+ */
+function isFiberLike(structure: Structure) {
+    const polymerSymmetryGroups = getPolymerSymmetryGroups(structure)
+    return (
+        polymerSymmetryGroups.length === 1 &&
+        polymerSymmetryGroups[0].units.length > 2 &&
+        polymerSymmetryGroups[0].units[0].polymerElements.length < 15
+    )
+}
+
+function hasHighSymmetry(structure: Structure) {
+    const polymerSymmetryGroups = getPolymerSymmetryGroups(structure)
+    return (
+        polymerSymmetryGroups.length > 1 &&
+        polymerSymmetryGroups[0].units.length > 10
+    )
+}
+
+export enum StructureSize { Small, Medium, Large, Huge, Gigantic }
+
+export function getStructureSize(structure: Structure): StructureSize {
+    if (structure.polymerResidueCount >= 12000) {
+        if (hasHighSymmetry(structure)) {
+            return StructureSize.Huge
+        } else {
+            return StructureSize.Gigantic
+        }
+    } else if (isFiberLike(structure)) {
+        return StructureSize.Small
+    } else if (structure.polymerResidueCount < 10) {
+        return StructureSize.Small
+    } else if (structure.polymerResidueCount < 1500) {
+        return StructureSize.Medium
+    } else {
+        return StructureSize.Large
+    }
+}

+ 7 - 14
src/structure-viewer/helpers/volume.ts

@@ -11,32 +11,25 @@ import { PluginContext } from 'molstar/lib/mol-plugin/context';
 import { InitVolumeStreaming, CreateVolumeStreamingInfo } from 'molstar/lib/mol-plugin/behavior/dynamic/volume-streaming/transformers';
 import { ParamDefinition as PD } from 'molstar/lib/mol-util/param-definition';
 import { Model } from 'molstar/lib/mol-model/structure';
-import { MmcifFormat } from 'molstar/lib/mol-model-formats/structure/mmcif';
+import { modelHasMap } from './util';
 
 export class VolumeData {
+    get customState() {
+        return this.plugin.customState as StructureViewerState
+    }
+
     get state() {
         return this.plugin.state.dataState;
     }
 
     async init() {
-        const { props } = (this.plugin.customState as StructureViewerState)
+        const { props } = this.customState
         const model = this.state.select(StateElements.Model)[0].obj;
         const asm = this.state.select(StateElements.Assembly)[0].obj;
         if (!model || !asm) return
 
         const m = model.data as Model
-        if (!MmcifFormat.is(m.sourceData)) return
-        const { db } = m.sourceData.data
-        const hasXrayMap = db.pdbx_database_status.status_code_sf.value(0) === 'REL'
-        let hasEmMap = false
-        for (let i = 0, il = db.pdbx_database_related._rowCount; i < il; ++i) {
-            if (db.pdbx_database_related.db_name.value(i).toUpperCase() === 'EMDB') {
-                hasEmMap = true
-                break
-            }
-        }
-
-        if (hasXrayMap || hasEmMap) {
+        if (modelHasMap(m)) {
             const params = PD.getDefaultValues(InitVolumeStreaming.definition.params!(asm, this.plugin));
             params.defaultView = 'selection-box';
             params.options.behaviorRef = StateElements.VolumeStreaming;

+ 0 - 28
src/structure-viewer/ui/structure.tsx

@@ -12,8 +12,6 @@ import { ParamDefinition as PD } from 'molstar/lib/mol-util/param-definition';
 import { StateObject, StateTree, StateSelection } from 'molstar/lib/mol-state';
 import { PluginStateObject as PSO } from 'molstar/lib/mol-plugin/state/objects';
 import { StateTransforms } from 'molstar/lib/mol-plugin/state/transforms';
-import { Model } from 'molstar/lib/mol-model/structure';
-import { MmcifFormat } from 'molstar/lib/mol-model-formats/structure/mmcif';
 import { stringToWords } from 'molstar/lib/mol-util/string';
 import { ModelSymmetry } from 'molstar/lib/mol-model-formats/structure/property/symmetry';
 import { AssemblySymmetryProvider } from 'molstar/lib/mol-model-props/rcsb/assembly-symmetry'
@@ -324,30 +322,4 @@ export class StructureControls<P, S extends StructureControlsState> extends Coll
             <ParameterControls params={this.getParams()} values={this.values} onChange={this.onChange} isDisabled={this.state.isDisabled} />
         </div>
     }
-}
-
-function modelHasSymmetry(model: Model) {
-    if (!MmcifFormat.is(model.sourceData)) return false
-    const { db } = model.sourceData.data
-    return (
-        db.symmetry._rowCount === 1 && db.cell._rowCount === 1 && !(
-            db.symmetry.Int_Tables_number.value(0) === 1 &&
-            db.cell.angle_alpha.value(0) === 90 &&
-            db.cell.angle_beta.value(0) === 90 &&
-            db.cell.angle_gamma.value(0) === 90 &&
-            db.cell.length_a.value(0) === 1 &&
-            db.cell.length_b.value(0) === 1 &&
-            db.cell.length_c.value(0) === 1
-        )
-    )
-}
-
-function modelFromCrystallography(model: Model) {
-    if (!MmcifFormat.is(model.sourceData)) return false
-    const { db } = model.sourceData.data
-    for (let i = 0; i < db.exptl.method.rowCount; i++) {
-        const v = db.exptl.method.value(i).toUpperCase()
-        if (v.indexOf('DIFFRACTION') >= 0) return true
-    }
-    return false
 }