Browse Source

add CustomStructureProperty.type determining inheritance

Alexander Rose 5 years ago
parent
commit
f85e3e76fd

+ 9 - 5
src/mol-model-props/common/custom-property-registry.ts

@@ -89,22 +89,25 @@ namespace CustomStructureProperty {
         readonly getParams: (data: Structure) => Params
         readonly isApplicable: (data: Structure) => boolean
         readonly compute: (ctx: RuntimeContext, data: Structure, props: PD.Values<Params>) => Promise<Value>
+        readonly type: 'root' | 'local'
     }
 
-    // TODO currently this always uses .inheritedPropertyData
     export function createProvider<Params extends PD.Params, Value>(builder: ProviderBuilder<Params, Value>): CustomStructureProperty.Provider<Params, Value> {
+        const descriptorName = builder.descriptor.name
+        const propertyDataName = builder.type === 'root' ? 'inheritedPropertyData' : 'currentPropertyData'
+
         const get = (data: Structure) => {
-            if (!(builder.descriptor.name in data.inheritedPropertyData)) {
-                (data.inheritedPropertyData[builder.descriptor.name] as CustomStructureProperty.Property<PD.Values<Params>, Value>) = {
+            if (!(descriptorName in data[propertyDataName])) {
+                (data[propertyDataName][descriptorName] as CustomStructureProperty.Property<PD.Values<Params>, Value>) = {
                     props: { ...PD.getDefaultValues(builder.getParams(data)) },
                     data: ValueBox.create(undefined)
                 }
             }
-            return data.inheritedPropertyData[builder.descriptor.name] as CustomStructureProperty.Property<PD.Values<Params>, Value>;
+            return data[propertyDataName][descriptorName] as CustomStructureProperty.Property<PD.Values<Params>, Value>;
         }
         const set = (data: Structure, props: PD.Values<Params>, value: Value | undefined) => {
             const property = get(data);
-            (data.inheritedPropertyData[builder.descriptor.name] as CustomStructureProperty.Property<PD.Values<Params>, Value>) = {
+            (data[propertyDataName][descriptorName] as CustomStructureProperty.Property<PD.Values<Params>, Value>) = {
                 props,
                 data: ValueBox.withValue(property.data, value)
             };
@@ -116,6 +119,7 @@ namespace CustomStructureProperty {
             getParams: builder.getParams,
             isApplicable: builder.isApplicable,
             attach: (data: Structure, props: Partial<PD.Values<Params>> = {}) => Task.create(`Attach ${builder.label}`, async ctx => {
+                if (builder.type === 'root') data = data.root
                 const property = get(data)
                 const p = { ...property.props, ...props }
                 if (property.data.value && PD.areEqual(builder.defaultParams, property.props, p)) return

+ 1 - 0
src/mol-model-props/computed/accessible-surface-area.ts

@@ -26,6 +26,7 @@ export const AccessibleSurfaceAreaProvider: CustomStructureProperty.Provider<Acc
         name: 'molstar_accessible_surface_area',
         // TODO `cifExport` and `symbol`
     }),
+    type: 'root',
     defaultParams: AccessibleSurfaceAreaParams,
     getParams: (data: Structure) => AccessibleSurfaceAreaParams,
     isApplicable: (data: Structure) => true,

+ 1 - 0
src/mol-model-props/computed/interactions.ts

@@ -25,6 +25,7 @@ export const InteractionsProvider: CustomStructureProperty.Provider<Interactions
         name: 'molstar_computed_interactions',
         // TODO `cifExport` and `symbol`
     }),
+    type: 'local',
     defaultParams: InteractionsParams,
     getParams: (data: Structure) => InteractionsParams,
     isApplicable: (data: Structure) => true,

+ 1 - 1
src/mol-model-props/computed/secondary-structure.ts

@@ -52,6 +52,7 @@ export const SecondaryStructureProvider: CustomStructureProperty.Provider<Second
         name: 'molstar_computed_secondary_structure',
         // TODO `cifExport` and `symbol`
     }),
+    type: 'root',
     defaultParams: SecondaryStructureParams,
     getParams: getSecondaryStructureParams,
     isApplicable: (data: Structure) => true,
@@ -66,7 +67,6 @@ export const SecondaryStructureProvider: CustomStructureProperty.Provider<Second
 
 async function computeDssp(structure: Structure, props: DSSPComputationProps): Promise<SecondaryStructureValue> {
     // TODO take inter-unit hbonds into account for bridge, ladder, sheet assignment
-    // TODO store unit-only secStruc as custom unit property???
     // TODO use Zhang-Skolnik for CA alpha only parts or for coarse parts with per-residue elements
     const map = new Map<number, SecondaryStructure>()
     for (let i = 0, il = structure.unitSymmetryGroups.length; i < il; ++i) {

+ 1 - 0
src/mol-model-props/computed/valence-model.ts

@@ -25,6 +25,7 @@ export const ValenceModelProvider: CustomStructureProperty.Provider<ValenceModel
         name: 'molstar_computed_valence_model',
         // TODO `cifExport` and `symbol`
     }),
+    type: 'local',
     defaultParams: ValenceModelParams,
     getParams: (data: Structure) => ValenceModelParams,
     isApplicable: (data: Structure) => true,

+ 1 - 1
src/mol-repr/structure/representation/cartoon.ts

@@ -64,6 +64,6 @@ export const CartoonRepresentationProvider: StructureRepresentationProvider<Cart
     defaultSizeTheme: 'uniform',
     isApplicable: (structure: Structure) => structure.polymerResidueCount > 0,
     ensureDependencies: (structure: Structure) => {
-        return SecondaryStructureProvider.attach(structure.root)
+        return SecondaryStructureProvider.attach(structure)
     }
 }

+ 1 - 1
src/mol-repr/structure/representation/interactions.ts

@@ -44,6 +44,6 @@ export const InteractionsRepresentationProvider: StructureRepresentationProvider
     defaultSizeTheme: 'uniform',
     isApplicable: (structure: Structure) => structure.elementCount > 0,
     ensureDependencies: (structure: Structure) => {
-        return InteractionsProvider.attach(structure.root)
+        return InteractionsProvider.attach(structure)
     }
 }

+ 6 - 19
src/mol-repr/structure/visual/interactions-intra-unit-cylinder.ts

@@ -7,7 +7,7 @@
 import { Unit, Bond, Structure, StructureElement } from '../../../mol-model/structure';
 import { Vec3 } from '../../../mol-math/linear-algebra';
 import { Loci, EmptyLoci } from '../../../mol-model/loci';
-import { Interval, SortedArray, OrderedSet } from '../../../mol-data/int';
+import { Interval, OrderedSet } from '../../../mol-data/int';
 import { ParamDefinition as PD } from '../../../mol-util/param-definition';
 import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
 import { PickingId } from '../../../mol-geo/geometry/picking';
@@ -26,11 +26,9 @@ async function createIntraUnitInteractionsCylinderMesh(ctx: VisualContext, unit:
     const interactions = InteractionsProvider.getValue(structure).value!
     const { features, links } = interactions.get(unit.id)!
 
-    const { x, y, z, offsets, members } = features
+    const { x, y, z } = features
     const { edgeCount, a, b } = links
     const { sizeFactor } = props
-    const { elements } = unit
-    const rootElements = structure.root.unitMap.get(unit.id).elements
 
     if (!edgeCount) return Mesh.createEmpty(mesh)
 
@@ -44,15 +42,7 @@ async function createIntraUnitInteractionsCylinderMesh(ctx: VisualContext, unit:
         order: (edgeIndex: number) => 1,
         flags: (edgeIndex: number) => BondType.Flag.MetallicCoordination, // TODO
         radius: (edgeIndex: number) => sizeFactor,
-        ignore: elements !== rootElements ? (edgeIndex: number) => {
-            for (let i = offsets[a[edgeIndex]], il = offsets[a[edgeIndex] + 1]; i < il; ++i) {
-                if (!SortedArray.has(elements, rootElements[members[i]])) return true
-            }
-            for (let i = offsets[b[edgeIndex]], il = offsets[b[edgeIndex] + 1]; i < il; ++i) {
-                if (!SortedArray.has(elements, rootElements[members[i]])) return true
-            }
-            return false
-        } : () => false
+        ignore: () => false
     }
 
     return createBondCylinderMesh(ctx, builderProps, props, mesh)
@@ -87,14 +77,13 @@ function getLinkLoci(pickingId: PickingId, structureGroup: StructureGroup, id: n
     const { objectId, instanceId, groupId } = pickingId
     if (id === objectId) {
         const { structure, group } = structureGroup
-        // use corresponding unit from root structure
-        const unit = structure.root.unitMap.get(group.units[instanceId].id)
+        const unit = structure.unitMap.get(group.units[instanceId].id)
         if (Unit.isAtomic(unit)) {
             const interactions = InteractionsProvider.getValue(structure).value!
             const { features, links } = interactions.get(unit.id)!
             const { members, offsets } = features
             // TODO this uses the first member elements of the features of an interaction as a representative
-            return Bond.Loci(structure.root, [
+            return Bond.Loci(structure, [
                 Bond.Location(
                     unit, members[offsets[links.a[groupId]]],
                     unit, members[offsets[links.b[groupId]]]
@@ -141,9 +130,7 @@ function eachInteraction(loci: Loci, structureGroup: StructureGroup, apply: (int
             if (unitIdx !== undefined) {
                 const { offset } = links
                 const { indices, offsets } = elementsIndex
-                const rootElements = structure.root.unitMap.get(unit.id).elements
-                OrderedSet.forEach(e.indices, _v => {
-                    const v = SortedArray.indexOf(rootElements, e.unit.elements[_v])
+                OrderedSet.forEach(e.indices, v => {
                     for (let i = offsets[v], il = offsets[v + 1]; i < il; ++i) {
                         const f = indices[i]
                         for (let t = offset[f], _t = offset[f + 1]; t < _t; t++) {

+ 1 - 1
src/mol-theme/color/accessible-surface-area.ts

@@ -73,6 +73,6 @@ export const AccessibleSurfaceAreaColorThemeProvider: ColorTheme.Provider<Access
     defaultValues: PD.getDefaultValues(AccessibleSurfaceAreaColorThemeParams),
     isApplicable: (ctx: ThemeDataContext) => !!ctx.structure,
     ensureDependencies: (ctx: ThemeDataContext) => {
-        return ctx.structure ? AccessibleSurfaceAreaProvider.attach(ctx.structure.root) : Task.empty()
+        return ctx.structure ? AccessibleSurfaceAreaProvider.attach(ctx.structure) : Task.empty()
     }
 }

+ 1 - 1
src/mol-theme/color/interaction-type.ts

@@ -114,6 +114,6 @@ export const InteractionTypeColorThemeProvider: ColorTheme.Provider<InteractionT
     defaultValues: PD.getDefaultValues(InteractionTypeColorThemeParams),
     isApplicable: (ctx: ThemeDataContext) => !!ctx.structure,
     ensureDependencies: (ctx: ThemeDataContext) => {
-        return ctx.structure ? InteractionsProvider.attach(ctx.structure.root) : Task.empty()
+        return ctx.structure ? InteractionsProvider.attach(ctx.structure) : Task.empty()
     }
 }

+ 1 - 1
src/mol-theme/color/secondary-structure.ts

@@ -118,6 +118,6 @@ export const SecondaryStructureColorThemeProvider: ColorTheme.Provider<Secondary
     defaultValues: PD.getDefaultValues(SecondaryStructureColorThemeParams),
     isApplicable: (ctx: ThemeDataContext) => !!ctx.structure,
     ensureDependencies: (ctx: ThemeDataContext) => {
-        return ctx.structure ? SecondaryStructureProvider.attach(ctx.structure.root) : Task.empty()
+        return ctx.structure ? SecondaryStructureProvider.attach(ctx.structure) : Task.empty()
     }
 }