Browse Source

add validation-report preset

Alexander Rose 5 years ago
parent
commit
6173520ad0

+ 31 - 27
src/mol-plugin-state/builder/structure/representation-preset.ts

@@ -17,23 +17,41 @@ import { StaticStructureComponentType } from '../../helpers/structure-component'
 import { StructureSelectionQueries as Q } from '../../helpers/structure-selection-query';
 
 export interface StructureRepresentationPresetProvider<P = any, S = {}> extends PresetProvider<PluginStateObject.Molecule.Structure, P, S> { }
+export function StructureRepresentationPresetProvider<P, S>(repr: StructureRepresentationPresetProvider<P, S>) { return repr; }
 export namespace StructureRepresentationPresetProvider {
     export type Params<P extends StructureRepresentationPresetProvider> = P extends StructureRepresentationPresetProvider<infer T> ? T : never;
     export type State<P extends StructureRepresentationPresetProvider> = P extends StructureRepresentationPresetProvider<infer _, infer S> ? S : never;
-}
-export function StructureRepresentationPresetProvider<P, S>(repr: StructureRepresentationPresetProvider<P, S>) { return repr; }
 
-export const CommonStructureRepresentationPresetParams = {
-    ignoreHydrogens: PD.Optional(PD.Boolean(false)),
-    quality: PD.Optional(PD.Select<VisualQuality>('auto', VisualQualityOptions)),
-    globalThemeName: PD.Optional(PD.Text<ColorTheme.BuiltIn>(''))
+    export const CommonParams = {
+        ignoreHydrogens: PD.Optional(PD.Boolean(false)),
+        quality: PD.Optional(PD.Select<VisualQuality>('auto', VisualQualityOptions)),
+        globalThemeName: PD.Optional(PD.Text<ColorTheme.BuiltIn>(''))
+    }
+    export type CommonParams = PD.ValuesFor<typeof CommonParams>
+
+    export function reprBuilder(plugin: PluginContext, params: CommonParams) {
+        const update = plugin.state.data.build();
+        const builder = plugin.builders.structure.representation;
+        const typeParams = {
+            quality: plugin.managers.structure.component.state.options.visualQuality,
+            ignoreHydrogens: !plugin.managers.structure.component.state.options.showHydrogens,
+        };
+        if (params.quality && params.quality !== 'auto') typeParams.quality = params.quality;
+        if (params.ignoreHydrogens !== void 0) typeParams.ignoreHydrogens = !!params.ignoreHydrogens;
+        const color: ColorTheme.BuiltIn | undefined = params.globalThemeName ? params.globalThemeName : void 0;
+
+        return { update, builder, color, typeParams };
+    }
 }
-export type CommonStructureRepresentationParams = PD.ValuesFor<typeof CommonStructureRepresentationPresetParams>
+
+const CommonParams = StructureRepresentationPresetProvider.CommonParams
+type CommonParams = StructureRepresentationPresetProvider.CommonParams
+const reprBuilder = StructureRepresentationPresetProvider.reprBuilder
 
 const auto = StructureRepresentationPresetProvider({
     id: 'preset-structure-representation-auto',
     display: { name: 'Automatic', group: 'Preset' },
-    params: () => CommonStructureRepresentationPresetParams,
+    params: () => CommonParams,
     apply(ref, params, plugin) {
         const structure = StateObjectRef.resolveAndCheck(plugin.state.data, ref)?.obj?.data;
         if (!structure) return { };
@@ -53,20 +71,6 @@ const auto = StructureRepresentationPresetProvider({
     }
 });
 
-function reprBuilder(plugin: PluginContext, params: CommonStructureRepresentationParams) {
-    const update = plugin.state.data.build();
-    const builder = plugin.builders.structure.representation;
-    const typeParams = {
-        quality: plugin.managers.structure.component.state.options.visualQuality,
-        ignoreHydrogens: !plugin.managers.structure.component.state.options.showHydrogens,
-    };
-    if (params.quality && params.quality !== 'auto') typeParams.quality = params.quality;
-    if (params.ignoreHydrogens !== void 0) typeParams.ignoreHydrogens = !!params.ignoreHydrogens;
-    const color: ColorTheme.BuiltIn | undefined = params.globalThemeName ? params.globalThemeName : void 0;
-
-    return { update, builder, color, typeParams };
-}
-
 const empty = StructureRepresentationPresetProvider({
     id: 'preset-structure-representation-empty',
     display: { name: 'Empty', group: 'Preset' },
@@ -78,7 +82,7 @@ const empty = StructureRepresentationPresetProvider({
 const polymerAndLigand = StructureRepresentationPresetProvider({
     id: 'preset-structure-representation-polymer-and-ligand',
     display: { name: 'Polymer & Ligand', group: 'Preset' },
-    params: () => CommonStructureRepresentationPresetParams,
+    params: () => CommonParams,
     async apply(ref, params, plugin) {
         const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
         if (!structureCell) return {};
@@ -113,7 +117,7 @@ const polymerAndLigand = StructureRepresentationPresetProvider({
 const proteinAndNucleic = StructureRepresentationPresetProvider({
     id: 'preset-structure-representation-protein-and-nucleic',
     display: { name: 'Protein & Nucleic', group: 'Preset' },
-    params: () => CommonStructureRepresentationPresetParams,
+    params: () => CommonParams,
     async apply(ref, params, plugin) {
         const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
         if (!structureCell) return {};
@@ -137,7 +141,7 @@ const proteinAndNucleic = StructureRepresentationPresetProvider({
 const coarseSurface = StructureRepresentationPresetProvider({
     id: 'preset-structure-representation-coarse-surface',
     display: { name: 'Coarse Surface', group: 'Preset' },
-    params: () => CommonStructureRepresentationPresetParams,
+    params: () => CommonParams,
     async apply(ref, params, plugin) {
         const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
         if (!structureCell) return {};
@@ -178,7 +182,7 @@ const coarseSurface = StructureRepresentationPresetProvider({
 const polymerCartoon = StructureRepresentationPresetProvider({
     id: 'preset-structure-representation-polymer-cartoon',
     display: { name: 'Polymer Cartoon', group: 'Preset' },
-    params: () => CommonStructureRepresentationPresetParams,
+    params: () => CommonParams,
     async apply(ref, params, plugin) {
         const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
         if (!structureCell) return {};
@@ -200,7 +204,7 @@ const polymerCartoon = StructureRepresentationPresetProvider({
 const atomicDetail = StructureRepresentationPresetProvider({
     id: 'preset-structure-representation-atomic-detail',
     display: { name: 'Atomic Detail', group: 'Preset' },
-    params: () => CommonStructureRepresentationPresetParams,
+    params: () => CommonParams,
     async apply(ref, params, plugin) {
         const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
         if (!structureCell) return {};

+ 40 - 1
src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts

@@ -17,6 +17,9 @@ import { cantorPairing } from '../../../../../mol-data/util';
 import { DefaultQueryRuntimeTable } from '../../../../../mol-script/runtime/query/compiler';
 import { StructureSelectionQuery, StructureSelectionCategory } from '../../../../../mol-plugin-state/helpers/structure-selection-query';
 import { MolScriptBuilder as MS } from '../../../../../mol-script/language/builder';
+import { Task } from '../../../../../mol-task';
+import { StructureRepresentationPresetProvider, PresetStructureRepresentations } from '../../../../../mol-plugin-state/builder/structure/representation-preset';
+import { StateObjectRef } from '../../../../../mol-state';
 
 export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean, showTooltip: boolean }>({
     name: 'rcsb-validation-report-prop',
@@ -50,6 +53,7 @@ export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean,
 
             this.ctx.representation.structure.registry.add(ClashesRepresentationProvider)
             this.ctx.query.structure.registry.add(hasClash)
+            this.ctx.builders.structure.representation.registerPreset(validationReportPreset)
         }
 
         update(p: { autoAttach: boolean, showTooltip: boolean }) {
@@ -74,6 +78,7 @@ export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean,
 
             this.ctx.representation.structure.registry.remove(ClashesRepresentationProvider)
             this.ctx.query.structure.registry.remove(hasClash)
+            this.ctx.builders.structure.representation.unregisterPreset(validationReportPreset)
         }
     },
     params: () => ({
@@ -279,4 +284,38 @@ const hasClash = StructureSelectionQuery('Residues with Clashes', MS.struct.modi
     ensureCustomProperties: (ctx, structure) => {
         return ValidationReportProvider.attach(ctx, structure.models[0])
     }
-})
+})
+
+//
+
+const validationReportPreset = StructureRepresentationPresetProvider({
+    id: 'preset-structure-representation-rcsb-validation-report',
+    display: { name: 'Validation Report', group: 'Preset' },
+    params: () => StructureRepresentationPresetProvider.CommonParams,
+    async apply(ref, params, plugin) {
+        const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
+        const model = structureCell?.obj?.data.model
+        if (!structureCell || !model) return {};
+
+        const colorTheme = GeometryQualityColorThemeProvider.name as any
+
+        await plugin.runTask(Task.create('Validation Report', async runtime => {
+            await ValidationReportProvider.attach({ fetch: plugin.fetch, runtime }, model)
+        }))
+
+        const { components, representations } = await PresetStructureRepresentations.auto.apply(ref, { ...params, globalThemeName: colorTheme }, plugin)
+
+        components.clashes = await plugin.builders.structure.tryCreateComponentFromExpression(structureCell, hasClash.expression, 'clashes', { label: 'Clashes' })
+
+        const { update, builder, typeParams, color } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
+        if (representations) {
+            (representations as any).clashes = components.clashes && {
+                ballAndStick: builder.buildRepresentation(update, components.clashes, { type: 'ball-and-stick', typeParams, color: colorTheme }),
+                snfg3d: builder.buildRepresentation<any>(update, components.clashes, { type: ClashesRepresentationProvider.name, typeParams, color }),
+            }
+        }
+
+        await plugin.updateDataState(update, { revertOnError: false });
+        return { components, representations };
+    }
+});