Browse Source

added StructureSymmetryMatesFromModel transform, fixes for findMatesRadius

Alexander Rose 5 years ago
parent
commit
00f9dcee4a

+ 13 - 3
src/mol-model/structure/structure/symmetry.ts

@@ -191,7 +191,13 @@ async function findMatesRadius(ctx: RuntimeContext, structure: Structure, radius
     const operators = getOperatorsCached333(symmetry, modelCenter);
     const lookup = structure.lookup3d;
 
-    const assembler = Structure.Builder();
+    // keep track of added invariant-unit and operator combinations
+    const added = new Set<string>()
+    function hash(unit: Unit, oper: SymmetryOperator) {
+        return `${unit.invariantId}|${oper.name}`
+    }
+
+    const assembler = Structure.Builder({ label: structure.label });
 
     const { units } = structure;
     const center = Vec3.zero();
@@ -204,13 +210,17 @@ async function findMatesRadius(ctx: RuntimeContext, structure: Structure, radius
             for (let uI = 0, _uI = closeUnits.count; uI < _uI; uI++) {
                 const closeUnit = units[closeUnits.indices[uI]];
                 if (!closeUnit.lookup3d.check(center[0], center[1], center[2], boundingSphere.radius + radius)) continue;
-                assembler.addWithOperator(unit, oper);
+
+                const h = hash(unit, oper)
+                if (!added.has(h)) {
+                    assembler.addWithOperator(unit, oper);
+                    added.add(h)
+                }
             }
         }
         if (ctx.shouldUpdate) await ctx.update('Building symmetry...');
     }
 
-
     return assembler.getStructure();
 }
 

+ 1 - 0
src/mol-plugin/index.ts

@@ -42,6 +42,7 @@ export const DefaultPluginSpec: PluginSpec = {
         PluginSpec.Action(StateTransforms.Model.TrajectoryFromPDB),
         PluginSpec.Action(StateTransforms.Model.StructureAssemblyFromModel),
         PluginSpec.Action(StateTransforms.Model.StructureSymmetryFromModel),
+        PluginSpec.Action(StateTransforms.Model.StructureSymmetryMatesFromModel),
         PluginSpec.Action(TransformStructureConformation),
         PluginSpec.Action(StateTransforms.Model.StructureFromModel),
         PluginSpec.Action(StateTransforms.Model.StructureFromTrajectory),

+ 26 - 0
src/mol-plugin/state/transforms/model.ts

@@ -40,6 +40,7 @@ export { StructureFromTrajectory };
 export { StructureFromModel };
 export { StructureAssemblyFromModel };
 export { StructureSymmetryFromModel };
+export { StructureSymmetryMatesFromModel };
 export { TransformStructureConformation };
 export { TransformStructureConformationByMatrix };
 export { StructureSelectionFromExpression };
@@ -301,6 +302,31 @@ const StructureSymmetryFromModel = PluginStateTransform.BuiltIn({
     }
 });
 
+type StructureSymmetryMatesFromModel = typeof StructureSymmetryMatesFromModel
+const StructureSymmetryMatesFromModel = PluginStateTransform.BuiltIn({
+    name: 'structure-symmetry-mates-from-model',
+    display: { name: 'Structure Symmetry Mates', description: 'Create molecular structure symmetry mates.' },
+    from: SO.Molecule.Model,
+    to: SO.Molecule.Structure,
+    params(a) {
+        return {
+            radius: PD.Numeric(5),
+        }
+    }
+})({
+    apply({ a, params }, plugin: PluginContext) {
+        return Task.create('Build Symmetry Mates', async ctx => {
+            const { radius } = params
+            const model = a.data;
+            const base = Structure.ofModel(model);
+            const s = await StructureSymmetry.builderSymmetryMates(base, radius).runInContext(ctx);
+            await ensureSecondaryStructure(s)
+            const props = { label: `Symmetry Mates`, description: structureDesc(s) };
+            return new SO.Molecule.Structure(s, props);
+        })
+    }
+});
+
 const _translation = Vec3.zero(), _m = Mat4.zero(), _n = Mat4.zero();
 type TransformStructureConformation = typeof TransformStructureConformation
 const TransformStructureConformation = PluginStateTransform.BuiltIn({