Bläddra i källkod

handle dynamicBonds in root structure helper

Alexander Rose 3 år sedan
förälder
incheckning
8999c3097d

+ 2 - 2
src/mol-model/structure/structure/structure.ts

@@ -759,12 +759,12 @@ namespace Structure {
      * Generally, a single unit corresponds to a single chain, with the exception
      * of consecutive "single atom chains" with same entity_id and same auth_asym_id.
      */
-    export function ofModel(model: Model, dynamicBonds = false): Structure {
+    export function ofModel(model: Model, props: Props = {}): Structure {
         const chains = model.atomicHierarchy.chainAtomSegments;
         const { index } = model.atomicHierarchy;
         const { auth_asym_id } = model.atomicHierarchy.chains;
         const { atomicChainOperatorMappinng } = model;
-        const builder = new StructureBuilder({ label: model.label, dynamicBonds });
+        const builder = new StructureBuilder({ label: model.label, ...props });
 
         for (let c = 0 as ChainIndex; c < chains.count; c++) {
             const operator = atomicChainOperatorMappinng.get(c) || SymmetryOperator.Default;

+ 15 - 4
src/mol-model/structure/structure/symmetry.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -27,7 +27,11 @@ namespace StructureSymmetry {
             if (!assembly) throw new Error(`Assembly '${asmName}' is not defined.`);
 
             const coordinateSystem = SymmetryOperator.create(assembly.id, Mat4.identity(), { assembly: { id: assembly.id, operId: 0, operList: [] } });
-            const assembler = Structure.Builder({ coordinateSystem, label: structure.label });
+            const assembler = Structure.Builder({
+                coordinateSystem,
+                label: structure.label,
+                dynamicBonds: structure.dynamicBonds
+            });
 
             const queryCtx = new QueryContext(structure);
 
@@ -57,7 +61,11 @@ namespace StructureSymmetry {
             if (models.length !== 1) throw new Error('Can only build symmetry assemblies from structures based on 1 model.');
 
             const modelCenter = Vec3();
-            const assembler = Structure.Builder({ label: structure.label, representativeModel: models[0] });
+            const assembler = Structure.Builder({
+                label: structure.label,
+                representativeModel: models[0],
+                dynamicBonds: structure.dynamicBonds
+            });
 
             const queryCtx = new QueryContext(structure);
 
@@ -266,7 +274,10 @@ async function findMatesRadius(ctx: RuntimeContext, structure: Structure, radius
         return `${unit.invariantId}|${oper.name}`;
     }
 
-    const assembler = Structure.Builder({ label: structure.label });
+    const assembler = Structure.Builder({
+        label: structure.label,
+        dynamicBonds: structure.dynamicBonds
+    });
 
     const { units } = structure;
     const center = Vec3.zero();

+ 2 - 2
src/mol-plugin-state/builder/structure/hierarchy-preset.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2020-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -132,7 +132,7 @@ async function applyCrystalSymmetry(props: { ijkMin: Vec3, ijkMax: Vec3, theme?:
 
     const structure = await builder.createStructure(modelProperties || model, {
         name: 'symmetry',
-        params: { ...props, dynamicBonds: false }
+        params: props
     });
     const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
 

+ 39 - 30
src/mol-plugin-state/helpers/root-structure.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -16,6 +16,11 @@ import { Assembly, Symmetry } from '../../mol-model/structure/model/properties/s
 import { PluginStateObject as SO } from '../objects';
 import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry';
 
+const CommonStructureParams = {
+    dynamicBonds: PD.Optional(PD.Boolean(false, { description: 'Ensure bonds are recalculated upon model changes. Also enables calculation of inter-unit bonds in water molecules.' })),
+};
+type CommonStructureProps = PD.ValuesFor<typeof CommonStructureParams>
+
 export namespace RootStructureDefinition {
     export function getParams(model?: Model, defaultValue?: 'auto' | 'model' | 'assembly' | 'symmetry' | 'symmetry-mates' | 'symmetry-assembly') {
         const symmetry = model && ModelSymmetry.Provider.get(model);
@@ -40,20 +45,22 @@ export namespace RootStructureDefinition {
         }
 
         const modes = {
-            auto: PD.EmptyGroup(),
-            model: PD.EmptyGroup(),
+            auto: PD.Group(CommonStructureParams),
+            model: PD.Group(CommonStructureParams),
             assembly: PD.Group({
                 id: PD.Optional(model
                     ? PD.Select(assemblyIds.length ? assemblyIds[0][0] : '', assemblyIds, { label: 'Asm Id', description: 'Assembly Id' })
-                    : PD.Text('', { label: 'Asm Id', description: 'Assembly Id (use empty for the 1st assembly)' }))
+                    : PD.Text('', { label: 'Asm Id', description: 'Assembly Id (use empty for the 1st assembly)' })),
+                ...CommonStructureParams
             }, { isFlat: true }),
             'symmetry-mates': PD.Group({
-                radius: PD.Numeric(5, { min: 0, max: 50, step: 1 })
+                radius: PD.Numeric(5, { min: 0, max: 50, step: 1 }),
+                ...CommonStructureParams
             }, { isFlat: true }),
             'symmetry': PD.Group({
                 ijkMin: PD.Vec3(Vec3.create(-1, -1, -1), { step: 1 }, { label: 'Min IJK', fieldLabels: { x: 'I', y: 'J', z: 'K' } }),
                 ijkMax: PD.Vec3(Vec3.create(1, 1, 1), { step: 1 }, { label: 'Max IJK', fieldLabels: { x: 'I', y: 'J', z: 'K' } }),
-                dynamicBonds: PD.Boolean(false),
+                ...CommonStructureParams
             }, { isFlat: true }),
             'symmetry-assembly': PD.Group({
                 generators: PD.ObjectList({
@@ -66,7 +73,8 @@ export namespace RootStructureDefinition {
                     asymIds: PD.MultiSelect([] as string[], asymIdsOptions)
                 }, e => `${e.asymIds.length} asym ids, ${e.operators.length} operators`, {
                     defaultValue: [] as { operators: { index: number, shift: Vec3 }[], asymIds: string[] }[]
-                })
+                }),
+                ...CommonStructureParams
             }, { isFlat: true })
         };
 
@@ -100,7 +108,7 @@ export namespace RootStructureDefinition {
         return true;
     }
 
-    async function buildAssembly(plugin: PluginContext, ctx: RuntimeContext, model: Model, id?: string) {
+    async function buildAssembly(plugin: PluginContext, ctx: RuntimeContext, model: Model, id?: string, props?: CommonStructureProps) {
         let asm: Assembly | undefined = void 0;
 
         const symmetry = ModelSymmetry.Provider.get(model);
@@ -119,7 +127,7 @@ export namespace RootStructureDefinition {
             }
         }
 
-        const base = Structure.ofModel(model);
+        const base = Structure.ofModel(model, props);
         if (!asm) {
             const label = { label: 'Model', description: Structure.elementDescription(base) };
             return new SO.Molecule.Structure(base, label);
@@ -127,56 +135,57 @@ export namespace RootStructureDefinition {
 
         id = asm.id;
         const s = await StructureSymmetry.buildAssembly(base, id!).runInContext(ctx);
-        const props = { label: `Assembly ${id}`, description: Structure.elementDescription(s) };
-        return new SO.Molecule.Structure(s, props);
+        const objProps = { label: `Assembly ${id}`, description: Structure.elementDescription(s) };
+        return new SO.Molecule.Structure(s, objProps);
     }
 
-    async function buildSymmetry(ctx: RuntimeContext, model: Model, ijkMin: Vec3, ijkMax: Vec3, dynamicBonds: boolean) {
-        const base = Structure.ofModel(model, dynamicBonds);
+    async function buildSymmetry(ctx: RuntimeContext, model: Model, ijkMin: Vec3, ijkMax: Vec3, props?: CommonStructureProps) {
+        const base = Structure.ofModel(model, props);
         const s = await StructureSymmetry.buildSymmetryRange(base, ijkMin, ijkMax).runInContext(ctx);
-        const props = { label: `Symmetry [${ijkMin}] to [${ijkMax}]`, description: Structure.elementDescription(s) };
-        return new SO.Molecule.Structure(s, props);
+        const objProps = { label: `Symmetry [${ijkMin}] to [${ijkMax}]`, description: Structure.elementDescription(s) };
+        return new SO.Molecule.Structure(s, objProps);
     }
 
-    async function buildSymmetryMates(ctx: RuntimeContext, model: Model, radius: number) {
-        const base = Structure.ofModel(model);
+    async function buildSymmetryMates(ctx: RuntimeContext, model: Model, radius: number, props?: CommonStructureProps) {
+        const base = Structure.ofModel(model, props);
         const s = await StructureSymmetry.builderSymmetryMates(base, radius).runInContext(ctx);
-        const props = { label: `Symmetry Mates`, description: Structure.elementDescription(s) };
-        return new SO.Molecule.Structure(s, props);
+        const objProps = { label: `Symmetry Mates`, description: Structure.elementDescription(s) };
+        return new SO.Molecule.Structure(s, objProps);
     }
 
-    async function buildSymmetryAssembly(ctx: RuntimeContext, model: Model, generators: StructureSymmetry.Generators, symmetry: Symmetry) {
-        const base = Structure.ofModel(model);
+    async function buildSymmetryAssembly(ctx: RuntimeContext, model: Model, generators: StructureSymmetry.Generators, symmetry: Symmetry, props?: CommonStructureProps) {
+        const base = Structure.ofModel(model, props);
         const s = await StructureSymmetry.buildSymmetryAssembly(base, generators, symmetry).runInContext(ctx);
-        const props = { label: `Symmetry Assembly`, description: Structure.elementDescription(s) };
-        return new SO.Molecule.Structure(s, props);
+        const objProps = { label: `Symmetry Assembly`, description: Structure.elementDescription(s) };
+        return new SO.Molecule.Structure(s, objProps);
     }
 
     export async function create(plugin: PluginContext, ctx: RuntimeContext, model: Model, params?: Params): Promise<SO.Molecule.Structure> {
+        const props = params?.params;
         const symmetry = ModelSymmetry.Provider.get(model);
         if (!symmetry || !params || params.name === 'model') {
-            const s = Structure.ofModel(model);
+            const s = Structure.ofModel(model, props);
             return new SO.Molecule.Structure(s, { label: 'Model', description: Structure.elementDescription(s) });
         }
         if (params.name === 'auto') {
             if (symmetry.assemblies.length === 0) {
-                const s = Structure.ofModel(model);
+                const s = Structure.ofModel(model, props);
                 return new SO.Molecule.Structure(s, { label: 'Model', description: Structure.elementDescription(s) });
             } else {
-                return buildAssembly(plugin, ctx, model);
+                return buildAssembly(plugin, ctx, model, undefined, props);
             }
         }
         if (params.name === 'assembly') {
-            return buildAssembly(plugin, ctx, model, params.params.id);
+            return buildAssembly(plugin, ctx, model, params.params.id, props);
         }
         if (params.name === 'symmetry') {
-            return buildSymmetry(ctx, model, params.params.ijkMin, params.params.ijkMax, params.params.dynamicBonds);
+            return buildSymmetry(ctx, model, params.params.ijkMin, params.params.ijkMax, props);
         }
         if (params.name === 'symmetry-mates') {
-            return buildSymmetryMates(ctx, model, params.params.radius);
+            return buildSymmetryMates(ctx, model, params.params.radius, props);
         }
         if (params.name === 'symmetry-assembly') {
-            return buildSymmetryAssembly(ctx, model, params.params.generators, symmetry);
+            return buildSymmetryAssembly(ctx, model, params.params.generators, symmetry, props);
         }
 
         throw new Error(`Unknown represetation type: ${(params as any).name}`);