Browse Source

use bond location for repr bond iterator

- fix themes to handle Bond.Location (some did not)
Alexander Rose 4 years ago
parent
commit
181cfefa63

+ 7 - 4
src/extensions/cellpack/color/provided.ts

@@ -9,7 +9,7 @@ import { ParamDefinition as PD } from '../../../mol-util/param-definition';
 import { Color } from '../../../mol-util/color';
 import { ColorTheme, LocationColor } from '../../../mol-theme/color';
 import { ScaleLegend, TableLegend } from '../../../mol-util/legend';
-import { StructureElement, Model } from '../../../mol-model/structure';
+import { StructureElement, Model, Bond } from '../../../mol-model/structure';
 import { Location } from '../../../mol-model/location';
 import { CellPackInfoProvider } from '../property';
 
@@ -37,9 +37,12 @@ export function CellPackProvidedColorTheme(ctx: ThemeDataContext, props: PD.Valu
         }
 
         color = (location: Location): Color => {
-            return StructureElement.Location.is(location)
-                ? modelColor.get(Model.TrajectoryInfo.get(location.unit.model).index)!
-                : DefaultColor;
+            if (StructureElement.Location.is(location)) {
+                return modelColor.get(Model.TrajectoryInfo.get(location.unit.model).index)!;
+            } else if (Bond.isLocation(location)) {
+                return modelColor.get(Model.TrajectoryInfo.get(location.aUnit.model).index)!;
+            }
+            return DefaultColor;
         };
     } else {
         color = () => DefaultColor;

+ 10 - 1
src/extensions/pdbe/structure-quality-report/color.ts

@@ -6,7 +6,7 @@
 
 import { StructureQualityReport, StructureQualityReportProvider } from './prop';
 import { Location } from '../../../mol-model/location';
-import { StructureElement } from '../../../mol-model/structure';
+import { Bond, StructureElement } from '../../../mol-model/structure';
 import { ColorTheme, LocationColor } from '../../../mol-theme/color';
 import { ThemeDataContext } from '../../../mol-theme/theme';
 import { Color } from '../../../mol-util/color';
@@ -46,11 +46,16 @@ export function StructureQualityReportColorTheme(ctx: ThemeDataContext, props: P
 
     if (ctx.structure && !ctx.structure.isEmpty && ctx.structure.models[0].customProperties.has(StructureQualityReportProvider.descriptor)) {
         const getIssues = StructureQualityReport.getIssues;
+        const l = StructureElement.Location.create(ctx.structure);
 
         if (props.type.name === 'issue-count') {
             color = (location: Location) => {
                 if (StructureElement.Location.is(location)) {
                     return ValidationColors[Math.min(3, getIssues(location).length) + 1];
+                } else if (Bond.isLocation(location)) {
+                    l.unit = location.aUnit;
+                    l.element = location.aUnit.elements[location.aIndex];
+                    return ValidationColors[Math.min(3, getIssues(l).length) + 1];
                 }
                 return ValidationColors[0];
             };
@@ -59,6 +64,10 @@ export function StructureQualityReportColorTheme(ctx: ThemeDataContext, props: P
             color = (location: Location) => {
                 if (StructureElement.Location.is(location) && getIssues(location).indexOf(issue) >= 0) {
                     return ValidationColors[4];
+                } else if (Bond.isLocation(location)) {
+                    l.unit = location.aUnit;
+                    l.element = location.aUnit.elements[location.aIndex];
+                    return ValidationColors[Math.min(3, getIssues(l).length) + 1];
                 }
                 return ValidationColors[0];
             };

+ 15 - 5
src/extensions/rcsb/assembly-symmetry/color.ts

@@ -9,7 +9,7 @@ import { ColorTheme, LocationColor } from '../../../mol-theme/color';
 import { ParamDefinition as PD } from '../../../mol-util/param-definition';
 import { AssemblySymmetryProvider, AssemblySymmetry } from './prop';
 import { Color } from '../../../mol-util/color';
-import { Unit, StructureElement, StructureProperties } from '../../../mol-model/structure';
+import { Unit, StructureElement, StructureProperties, Bond } from '../../../mol-model/structure';
 import { Location } from '../../../mol-model/location';
 import { ScaleLegend, TableLegend } from '../../../mol-util/legend';
 import { getPalette, getPaletteParams } from '../../../mol-util/color/palette';
@@ -50,6 +50,8 @@ export function AssemblySymmetryClusterColorTheme(ctx: ThemeDataContext, props:
     const clusters = assemblySymmetry?.value?.clusters;
 
     if (clusters?.length && ctx.structure) {
+        const l = StructureElement.Location.create(ctx.structure);
+
         const clusterByMember = new Map<string, number>();
         for (let i = 0, il = clusters.length; i < il; ++i) {
             const { members } = clusters[i]!;
@@ -67,12 +69,20 @@ export function AssemblySymmetryClusterColorTheme(ctx: ThemeDataContext, props:
         legend = palette.legend;
 
         const _emptyList: any[] = [];
+        const getColor = (location: StructureElement.Location) => {
+            const { assembly } = location.unit.conformation.operator;
+            const asymId = getAsymId(location.unit)(location);
+            const cluster = clusterByMember.get(clusterMemberKey(asymId, assembly?.operList || _emptyList));
+            return cluster !== undefined ? palette.color(cluster) : DefaultColor;
+        };
+
         color = (location: Location): Color => {
             if (StructureElement.Location.is(location)) {
-                const { assembly } = location.unit.conformation.operator;
-                const asymId = getAsymId(location.unit)(location);
-                const cluster = clusterByMember.get(clusterMemberKey(asymId, assembly?.operList || _emptyList));
-                return cluster !== undefined ? palette.color(cluster) : DefaultColor;
+                return getColor(location);
+            } else if (Bond.isLocation(location)) {
+                l.unit = location.aUnit;
+                l.element = location.aUnit.elements[location.aIndex];
+                return getColor(l);
             }
             return DefaultColor;
         };

+ 12 - 6
src/extensions/rcsb/validation-report/color/density-fit.ts

@@ -8,7 +8,7 @@ import { ThemeDataContext } from '../../../../mol-theme/theme';
 import { ColorTheme, LocationColor } from '../../../../mol-theme/color';
 import { ParamDefinition as PD } from '../../../../mol-util/param-definition';
 import { Color, ColorScale } from '../../../../mol-util/color';
-import { StructureElement, Model } from '../../../../mol-model/structure';
+import { StructureElement, Model, ElementIndex, Bond } from '../../../../mol-model/structure';
 import { Location } from '../../../../mol-model/location';
 import { CustomProperty } from '../../../../mol-model-props/common/custom-property';
 import { ValidationReportProvider, ValidationReport } from '../prop';
@@ -37,13 +37,19 @@ export function DensityFitColorTheme(ctx: ThemeDataContext, props: {}): ColorThe
     if (validationReport?.value && model) {
         const { rsrz, rscc } = validationReport.value;
         const residueIndex = model.atomicHierarchy.residueAtomSegments.index;
+        const getColor = (element: ElementIndex) => {
+            const rsrzValue = rsrz.get(residueIndex[element]);
+            if (rsrzValue !== undefined) return scaleRsrz.color(rsrzValue);
+            const rsccValue = rscc.get(residueIndex[element]);
+            if (rsccValue !== undefined) return scaleRscc.color(rsccValue);
+            return DefaultColor;
+        };
+
         color = (location: Location): Color => {
             if (StructureElement.Location.is(location) && location.unit.model === model) {
-                const rsrzValue = rsrz.get(residueIndex[location.element]);
-                if (rsrzValue !== undefined) return scaleRsrz.color(rsrzValue);
-                const rsccValue = rscc.get(residueIndex[location.element]);
-                if (rsccValue !== undefined) return scaleRscc.color(rsccValue);
-                return DefaultColor;
+                return getColor(location.element);
+            } else if (Bond.isLocation(location) && location.aUnit.model === model) {
+                return getColor(location.aUnit.elements[location.aIndex]);
             }
             return DefaultColor;
         };

+ 27 - 23
src/extensions/rcsb/validation-report/color/geometry-quality.ts

@@ -8,7 +8,7 @@ import { ThemeDataContext } from '../../../../mol-theme/theme';
 import { ColorTheme, LocationColor } from '../../../../mol-theme/color';
 import { ParamDefinition as PD } from '../../../../mol-util/param-definition';
 import { Color } from '../../../../mol-util/color';
-import { StructureElement } from '../../../../mol-model/structure';
+import { Bond, ElementIndex, StructureElement } from '../../../../mol-model/structure';
 import { Location } from '../../../../mol-model/location';
 import { CustomProperty } from '../../../../mol-model-props/common/custom-property';
 import { ValidationReportProvider, ValidationReport } from '../prop';
@@ -59,31 +59,35 @@ export function GeometryQualityColorTheme(ctx: ThemeDataContext, props: PD.Value
         const residueIndex = model.atomicHierarchy.residueAtomSegments.index;
         const { polymerType } = model.atomicHierarchy.derived.residue;
         const ignore = new Set(props.ignore);
+        const getColor = (element: ElementIndex) => {
+            const rI = residueIndex[element];
+
+            const value = geometryIssues.get(rI);
+            if (value === undefined) return DefaultColor;
+
+            let count = SetUtils.differenceSize(value, ignore);
+
+            if (count > 0 && polymerType[rI] === PolymerType.NA) {
+                count = 0;
+                if (!ignore.has('clash') && clashes.getVertexEdgeCount(element) > 0) count += 1;
+                if (!ignore.has('mog-bond-outlier') && bondOutliers.index.has(element)) count += 1;
+                if (!ignore.has('mog-angle-outlier') && angleOutliers.index.has(element)) count += 1;
+            }
+
+            switch (count) {
+                case undefined: return DefaultColor;
+                case 0: return NoIssuesColor;
+                case 1: return OneIssueColor;
+                case 2: return TwoIssuesColor;
+                default: return ThreeOrMoreIssuesColor;
+            }
+        };
 
         color = (location: Location): Color => {
             if (StructureElement.Location.is(location) && location.unit.model === model) {
-                const { element } = location;
-                const rI = residueIndex[element];
-
-                const value = geometryIssues.get(rI);
-                if (value === undefined) return DefaultColor;
-
-                let count = SetUtils.differenceSize(value, ignore);
-
-                if (count > 0 && polymerType[rI] === PolymerType.NA) {
-                    count = 0;
-                    if (!ignore.has('clash') && clashes.getVertexEdgeCount(element) > 0) count += 1;
-                    if (!ignore.has('mog-bond-outlier') && bondOutliers.index.has(element)) count += 1;
-                    if (!ignore.has('mog-angle-outlier') && angleOutliers.index.has(element)) count += 1;
-                }
-
-                switch (count) {
-                    case undefined: return DefaultColor;
-                    case 0: return NoIssuesColor;
-                    case 1: return OneIssueColor;
-                    case 2: return TwoIssuesColor;
-                    default: return ThreeOrMoreIssuesColor;
-                }
+                return getColor(location.element);
+            } else if (Bond.isLocation(location) && location.aUnit.model === model) {
+                return getColor(location.aUnit.elements[location.aIndex]);
             }
             return DefaultColor;
         };

+ 9 - 3
src/extensions/rcsb/validation-report/color/random-coil-index.ts

@@ -8,7 +8,7 @@ import { ThemeDataContext } from '../../../../mol-theme/theme';
 import { ColorTheme, LocationColor } from '../../../../mol-theme/color';
 import { ParamDefinition as PD } from '../../../../mol-util/param-definition';
 import { Color, ColorScale } from '../../../../mol-util/color';
-import { StructureElement, Model } from '../../../../mol-model/structure';
+import { StructureElement, Model, ElementIndex, Bond } from '../../../../mol-model/structure';
 import { Location } from '../../../../mol-model/location';
 import { CustomProperty } from '../../../../mol-model-props/common/custom-property';
 import { ValidationReportProvider, ValidationReport } from '../prop';
@@ -31,10 +31,16 @@ export function RandomCoilIndexColorTheme(ctx: ThemeDataContext, props: {}): Col
 
     if (rci && model) {
         const residueIndex = model.atomicHierarchy.residueAtomSegments.index;
+        const getColor = (element: ElementIndex) => {
+            const value = rci.get(residueIndex[element]);
+            return value === undefined ? DefaultColor : scale.color(value);
+        };
+
         color = (location: Location): Color => {
             if (StructureElement.Location.is(location) && location.unit.model === model) {
-                const value = rci.get(residueIndex[location.element]);
-                return value === undefined ? DefaultColor : scale.color(value);
+                return getColor(location.element);
+            } else if (Bond.isLocation(location) && location.aUnit.model === model) {
+                return getColor(location.aUnit.elements[location.aIndex]);
             }
             return DefaultColor;
         };

+ 11 - 3
src/mol-model-props/computed/themes/accessible-surface-area.ts

@@ -9,7 +9,7 @@ import { ParamDefinition as PD } from '../../../mol-util/param-definition';
 import { Color, ColorScale } from '../../../mol-util/color';
 import { ThemeDataContext } from '../../../mol-theme/theme';
 import { ColorTheme, LocationColor } from '../../../mol-theme/color';
-import { StructureElement, Unit } from '../../../mol-model/structure';
+import { Bond, StructureElement, Unit } from '../../../mol-model/structure';
 import { AccessibleSurfaceAreaProvider } from '../accessible-surface-area';
 import { AccessibleSurfaceArea } from '../accessible-surface-area/shrake-rupley';
 import { CustomProperty } from '../../common/custom-property';
@@ -40,12 +40,20 @@ export function AccessibleSurfaceAreaColorTheme(ctx: ThemeDataContext, props: PD
     const contextHash = accessibleSurfaceArea ? hash2(accessibleSurfaceArea.id, accessibleSurfaceArea.version) : -1;
 
     if (accessibleSurfaceArea?.value && ctx.structure) {
+        const l = StructureElement.Location.create(ctx.structure);
         const asa = accessibleSurfaceArea.value;
+        const getColor = (location: StructureElement.Location) => {
+            const value = AccessibleSurfaceArea.getNormalizedValue(location, asa);
+            return value === -1 ? DefaultColor : scale.color(value);
+        };
 
         color = (location: Location): Color => {
             if (StructureElement.Location.is(location) && Unit.isAtomic(location.unit)) {
-                const value = AccessibleSurfaceArea.getNormalizedValue(location, asa);
-                return value === -1 ? DefaultColor : scale.color(value);
+                return getColor(location);
+            } else if (Bond.isLocation(location)) {
+                l.unit = location.aUnit;
+                l.element = location.aUnit.elements[location.aIndex];
+                return getColor(l);
             }
             return DefaultColor;
         };

+ 15 - 7
src/mol-repr/structure/visual/util/bond.ts

@@ -98,11 +98,15 @@ export namespace BondIterator {
         const unit = group.units[0];
         const groupCount = Unit.isAtomic(unit) ? unit.bonds.edgeCount * 2 : 0;
         const instanceCount = group.units.length;
-        const location = StructureElement.Location.create(structure);
+        const location = Bond.Location();
+        location.aStructure = structure;
+        location.bStructure = structure;
         const getLocation = (groupIndex: number, instanceIndex: number) => {
-            const unit = group.units[instanceIndex];
-            location.unit = unit;
-            location.element = unit.elements[(unit as Unit.Atomic).bonds.a[groupIndex]];
+            const unit = group.units[instanceIndex] as Unit.Atomic;
+            location.aUnit = unit;
+            location.bUnit = unit;
+            location.aIndex = unit.bonds.a[groupIndex];
+            location.bIndex = unit.bonds.b[groupIndex];
             return location;
         };
         return LocationIterator(groupCount, instanceCount, 1, getLocation);
@@ -111,11 +115,15 @@ export namespace BondIterator {
     export function fromStructure(structure: Structure): LocationIterator {
         const groupCount = structure.interUnitBonds.edgeCount;
         const instanceCount = 1;
-        const location = StructureElement.Location.create(structure);
+        const location = Bond.Location();
+        location.aStructure = structure;
+        location.bStructure = structure;
         const getLocation = (groupIndex: number) => {
             const bond = structure.interUnitBonds.edges[groupIndex];
-            location.unit = structure.unitMap.get(bond.unitA);
-            location.element = location.unit.elements[bond.indexA];
+            location.aUnit = structure.unitMap.get(bond.unitA);
+            location.aIndex = bond.indexA;
+            location.bUnit = structure.unitMap.get(bond.unitB);
+            location.bIndex = bond.indexB;
             return location;
         };
         return LocationIterator(groupCount, instanceCount, 1, getLocation, true);

+ 4 - 1
src/mol-theme/size/physical.ts

@@ -44,7 +44,10 @@ export function PhysicalSizeTheme(ctx: ThemeDataContext, props: PD.Values<Physic
         if (StructureElement.Location.is(location)) {
             size = scale * getPhysicalRadius(location.unit, location.element);
         } else if (Bond.isLocation(location)) {
-            size = scale * getPhysicalRadius(location.aUnit, location.aUnit.elements[location.aIndex]);
+            size = scale * Math.min(
+                getPhysicalRadius(location.aUnit, location.aUnit.elements[location.aIndex]),
+                getPhysicalRadius(location.bUnit, location.bUnit.elements[location.bIndex])
+            );
         } else {
             size = scale * DefaultSize;
         }