Преглед изворни кода

repr/theme/size providers now contain unique name

David Sehnal пре 5 година
родитељ
комит
341f9f8c91
50 измењених фајлова са 121 додато и 82 уклоњено
  1. 1 1
      src/apps/basic-wrapper/index.ts
  2. 2 3
      src/examples/proteopedia-wrapper/coloring.ts
  3. 2 2
      src/examples/proteopedia-wrapper/index.ts
  4. 1 0
      src/mol-model-props/common/custom-element-property.ts
  5. 2 1
      src/mol-model-props/computed/themes/accessible-surface-area.ts
  6. 2 1
      src/mol-model-props/computed/themes/interaction-type.ts
  7. 2 1
      src/mol-model-props/integrative/cross-link-restraint/color.ts
  8. 2 1
      src/mol-model-props/pdbe/themes/structure-quality-report.ts
  9. 2 1
      src/mol-model-props/rcsb/themes/assembly-symmetry-cluster.ts
  10. 2 1
      src/mol-model-props/rcsb/themes/density-fit.ts
  11. 2 1
      src/mol-model-props/rcsb/themes/geometry-quality.ts
  12. 2 1
      src/mol-model-props/rcsb/themes/random-coil-index.ts
  13. 5 7
      src/mol-plugin-state/helpers/structure-representation-params.ts
  14. 2 2
      src/mol-plugin/behavior/dynamic/custom-props/computed/accessible-surface-area.ts
  15. 2 2
      src/mol-plugin/behavior/dynamic/custom-props/computed/interactions.ts
  16. 2 4
      src/mol-plugin/behavior/dynamic/custom-props/integrative/cross-link-restraint.ts
  17. 2 2
      src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts
  18. 2 2
      src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts
  19. 6 8
      src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts
  20. 6 6
      src/mol-plugin/behavior/dynamic/selection/structure-representation-interaction.ts
  21. 1 1
      src/mol-repr/structure/registry.ts
  22. 1 1
      src/mol-repr/volume/registry.ts
  23. 4 2
      src/mol-theme/color.ts
  24. 2 1
      src/mol-theme/color/carbohydrate-symbol.ts
  25. 2 1
      src/mol-theme/color/chain-id.ts
  26. 2 1
      src/mol-theme/color/element-index.ts
  27. 2 1
      src/mol-theme/color/element-symbol.ts
  28. 2 1
      src/mol-theme/color/entity-source.ts
  29. 2 1
      src/mol-theme/color/hydrophobicity.ts
  30. 2 1
      src/mol-theme/color/illustrative.ts
  31. 2 1
      src/mol-theme/color/model-index.ts
  32. 2 1
      src/mol-theme/color/molecule-type.ts
  33. 2 1
      src/mol-theme/color/occupancy.ts
  34. 2 1
      src/mol-theme/color/operator-hkl.ts
  35. 2 1
      src/mol-theme/color/operator-name.ts
  36. 2 1
      src/mol-theme/color/polymer-id.ts
  37. 2 1
      src/mol-theme/color/polymer-index.ts
  38. 2 1
      src/mol-theme/color/residue-name.ts
  39. 2 1
      src/mol-theme/color/secondary-structure.ts
  40. 2 1
      src/mol-theme/color/sequence-id.ts
  41. 2 1
      src/mol-theme/color/shape-group.ts
  42. 2 1
      src/mol-theme/color/uncertainty.ts
  43. 2 1
      src/mol-theme/color/uniform.ts
  44. 2 1
      src/mol-theme/color/unit-index.ts
  45. 2 2
      src/mol-theme/size.ts
  46. 2 1
      src/mol-theme/size/physical.ts
  47. 2 1
      src/mol-theme/size/shape-group.ts
  48. 2 1
      src/mol-theme/size/uncertainty.ts
  49. 2 1
      src/mol-theme/size/uniform.ts
  50. 14 4
      src/mol-theme/theme.ts

+ 1 - 1
src/apps/basic-wrapper/index.ts

@@ -47,7 +47,7 @@ class BasicWrapper {
             }
         });
 
-        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(StripedResidues.propertyProvider.descriptor.name, StripedResidues.colorThemeProvider!);
+        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(StripedResidues.colorThemeProvider!);
         this.plugin.managers.lociLabels.addProvider(StripedResidues.labelProvider!);
         this.plugin.customModelProperties.register(StripedResidues.propertyProvider, true);
     }

+ 2 - 3
src/examples/proteopedia-wrapper/coloring.ts

@@ -94,7 +94,8 @@ export function createProteopediaCustomTheme(colors: number[]) {
         }
     }
 
-    const ProteopediaCustomColorThemeProvider: ColorTheme.Provider<ProteopediaCustomColorThemeParams> = {
+    return {
+        name: 'proteopedia-custom',
         label: 'Proteopedia Custom',
         category: 'Custom',
         factory: ProteopediaCustomColorTheme,
@@ -102,6 +103,4 @@ export function createProteopediaCustomTheme(colors: number[]) {
         defaultValues: PD.getDefaultValues(ProteopediaCustomColorThemeParams),
         isApplicable: (ctx: ThemeDataContext) => !!ctx.structure
     }
-
-    return ProteopediaCustomColorThemeProvider;
 }

+ 2 - 2
src/examples/proteopedia-wrapper/index.ts

@@ -67,8 +67,8 @@ class MolStarProteopediaWrapper {
 
         const customColoring = createProteopediaCustomTheme((options && options.customColorList) || []);
 
-        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add('proteopedia-custom', customColoring);
-        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(EvolutionaryConservation.propertyProvider.descriptor.name, EvolutionaryConservation.colorThemeProvider!);
+        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(customColoring);
+        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(EvolutionaryConservation.colorThemeProvider!);
         this.plugin.managers.lociLabels.addProvider(EvolutionaryConservation.labelProvider!);
         this.plugin.customModelProperties.register(EvolutionaryConservation.propertyProvider, true);
     }

+ 1 - 0
src/mol-model-props/common/custom-element-property.ts

@@ -98,6 +98,7 @@ namespace CustomElementProperty {
         }
 
         return {
+            name: modelProperty.descriptor.name,
             label: modelProperty.label,
             category: 'Custom',
             factory: Coloring,

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

@@ -64,7 +64,8 @@ export function AccessibleSurfaceAreaColorTheme(ctx: ThemeDataContext, props: PD
     }
 }
 
-export const AccessibleSurfaceAreaColorThemeProvider: ColorTheme.Provider<AccessibleSurfaceAreaColorThemeParams> = {
+export const AccessibleSurfaceAreaColorThemeProvider: ColorTheme.Provider<AccessibleSurfaceAreaColorThemeParams, 'accessible-surface-area'> = {
+    name: 'accessible-surface-area',
     label: 'Accessible Surface Area',
     category: ColorTheme.Category.Residue,
     factory: AccessibleSurfaceAreaColorTheme,

+ 2 - 1
src/mol-model-props/computed/themes/interaction-type.ts

@@ -106,7 +106,8 @@ export function InteractionTypeColorTheme(ctx: ThemeDataContext, props: PD.Value
     }
 }
 
-export const InteractionTypeColorThemeProvider: ColorTheme.Provider<InteractionTypeColorThemeParams> = {
+export const InteractionTypeColorThemeProvider: ColorTheme.Provider<InteractionTypeColorThemeParams, 'interaction-type'> = {
+    name: 'interaction-type',
     label: 'Interaction Type',
     category: ColorTheme.Category.Misc,
     factory: InteractionTypeColorTheme,

+ 2 - 1
src/mol-model-props/integrative/cross-link-restraint/color.ts

@@ -61,7 +61,8 @@ export function CrossLinkColorTheme(ctx: ThemeDataContext, props: PD.Values<Cros
     }
 }
 
-export const CrossLinkColorThemeProvider: ColorTheme.Provider<CrossLinkColorThemeParams> = {
+export const CrossLinkColorThemeProvider: ColorTheme.Provider<CrossLinkColorThemeParams, 'cross-link'> = {
+    name: 'cross-link',
     label: 'Cross Link',
     category: ColorTheme.Category.Misc,
     factory: CrossLinkColorTheme,

+ 2 - 1
src/mol-model-props/pdbe/themes/structure-quality-report.ts

@@ -77,7 +77,8 @@ export function StructureQualityReportColorTheme(ctx: ThemeDataContext, props: P
     }
 }
 
-export const StructureQualityReportColorThemeProvider: ColorTheme.Provider<Params> =  {
+export const StructureQualityReportColorThemeProvider: ColorTheme.Provider<Params, 'pdbe-structure-quality-report'> =  {
+    name: 'pdbe-structure-quality-report',
     label: 'Structure Quality Report',
     category: ColorTheme.Category.Validation,
     factory: StructureQualityReportColorTheme,

+ 2 - 1
src/mol-model-props/rcsb/themes/assembly-symmetry-cluster.ts

@@ -91,7 +91,8 @@ export function AssemblySymmetryClusterColorTheme(ctx: ThemeDataContext, props:
     }
 }
 
-export const AssemblySymmetryClusterColorThemeProvider: ColorTheme.Provider<AssemblySymmetryClusterColorThemeParams> = {
+export const AssemblySymmetryClusterColorThemeProvider: ColorTheme.Provider<AssemblySymmetryClusterColorThemeParams, AssemblySymmetry.Tag.Cluster> = {
+    name: AssemblySymmetry.Tag.Cluster,
     label: 'Assembly Symmetry Cluster',
     category: ColorTheme.Category.Symmetry,
     factory: AssemblySymmetryClusterColorTheme,

+ 2 - 1
src/mol-model-props/rcsb/themes/density-fit.ts

@@ -60,7 +60,8 @@ export function DensityFitColorTheme(ctx: ThemeDataContext, props: {}): ColorThe
     }
 }
 
-export const DensityFitColorThemeProvider: ColorTheme.Provider<{}> = {
+export const DensityFitColorThemeProvider: ColorTheme.Provider<{}, ValidationReport.Tag.DensityFit> = {
+    name: ValidationReport.Tag.DensityFit,
     label: 'Density Fit',
     category: ColorTheme.Category.Validation,
     factory: DensityFitColorTheme,

+ 2 - 1
src/mol-model-props/rcsb/themes/geometry-quality.ts

@@ -100,7 +100,8 @@ export function GeometryQualityColorTheme(ctx: ThemeDataContext, props: PD.Value
     }
 }
 
-export const GeometryQualityColorThemeProvider: ColorTheme.Provider<GeometricQualityColorThemeParams> = {
+export const GeometryQualityColorThemeProvider: ColorTheme.Provider<GeometricQualityColorThemeParams, ValidationReport.Tag.GeometryQuality> = {
+    name: ValidationReport.Tag.GeometryQuality,
     label: 'Geometry Quality',
     category: ColorTheme.Category.Validation,
     factory: GeometryQualityColorTheme,

+ 2 - 1
src/mol-model-props/rcsb/themes/random-coil-index.ts

@@ -51,7 +51,8 @@ export function RandomCoilIndexColorTheme(ctx: ThemeDataContext, props: {}): Col
     }
 }
 
-export const RandomCoilIndexColorThemeProvider: ColorTheme.Provider<{}> = {
+export const RandomCoilIndexColorThemeProvider: ColorTheme.Provider<{}, ValidationReport.Tag.RandomCoilIndex> = {
+    name: ValidationReport.Tag.RandomCoilIndex,
     label: 'Random Coil Index',
     category: ColorTheme.Category.Validation,
     factory: RandomCoilIndexColorTheme,

+ 5 - 7
src/mol-plugin-state/helpers/structure-representation-params.ts

@@ -80,20 +80,18 @@ function createParamsProvider(ctx: PluginContext, structure: Structure, props: S
     const reprParams = Object.assign(reprDefaultParams, props.typeParams);
     
     const color = props.color || themeCtx.colorThemeRegistry.get(repr.defaultColorTheme.name);
-    const colorName = themeCtx.colorThemeRegistry.getName(color);
     const colorDefaultParams = PD.getDefaultValues(color.getParams(themeDataCtx));
-    if (colorName === repr.defaultColorTheme.name) Object.assign(colorDefaultParams, repr.defaultColorTheme.props);
+    if (color.name === repr.defaultColorTheme.name) Object.assign(colorDefaultParams, repr.defaultColorTheme.props);
     const colorParams = Object.assign(colorDefaultParams, props.colorParams);
 
     const size = props.size || themeCtx.sizeThemeRegistry.get(repr.defaultSizeTheme.name);
-    const sizeName = themeCtx.sizeThemeRegistry.getName(size);
     const sizeDefaultParams = PD.getDefaultValues(size.getParams(themeDataCtx));
-    if (sizeName === repr.defaultSizeTheme.name) Object.assign(sizeDefaultParams, repr.defaultSizeTheme.props);
+    if (size.name === repr.defaultSizeTheme.name) Object.assign(sizeDefaultParams, repr.defaultSizeTheme.props);
     const sizeParams = Object.assign(sizeDefaultParams, props.sizeParams);
 
     return ({
-        type: { name: ctx.structureRepresentation.registry.getName(repr), params: reprParams },
-        colorTheme: { name: colorName, params: colorParams },
-        sizeTheme: { name: sizeName, params: sizeParams }
+        type: { name: repr.name, params: reprParams },
+        colorTheme: { name: color.name, params: colorParams },
+        sizeTheme: { name: size.name, params: sizeParams }
     });
 }

+ 2 - 2
src/mol-plugin/behavior/dynamic/custom-props/computed/accessible-surface-area.ts

@@ -40,7 +40,7 @@ export const AccessibleSurfaceArea = PluginBehavior.create<{ autoAttach: boolean
             DefaultQueryRuntimeTable.addCustomProp(this.provider.descriptor);
 
             this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add('accessible-surface-area', AccessibleSurfaceAreaColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(AccessibleSurfaceAreaColorThemeProvider)
             this.ctx.managers.lociLabels.addProvider(this.label);
         }
 
@@ -49,7 +49,7 @@ export const AccessibleSurfaceArea = PluginBehavior.create<{ autoAttach: boolean
             // DefaultQueryRuntimeTable.removeCustomProp(this.provider.descriptor);
 
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove('accessible-surface-area')
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(AccessibleSurfaceAreaColorThemeProvider)
             this.ctx.managers.lociLabels.removeProvider(this.label);
         }
     },

+ 2 - 2
src/mol-plugin/behavior/dynamic/custom-props/computed/interactions.ts

@@ -99,14 +99,14 @@ export const Interactions = PluginBehavior.create<{ autoAttach: boolean, showToo
 
         register(): void {
             this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add('interaction-type', InteractionTypeColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(InteractionTypeColorThemeProvider)
             this.ctx.managers.lociLabels.addProvider(this.label);
             this.ctx.structureRepresentation.registry.add(InteractionsRepresentationProvider)
         }
 
         unregister() {
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove('interaction-type')
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(InteractionTypeColorThemeProvider)
             this.ctx.managers.lociLabels.removeProvider(this.label);
             this.ctx.structureRepresentation.registry.remove(InteractionsRepresentationProvider)
         }

+ 2 - 4
src/mol-plugin/behavior/dynamic/custom-props/integrative/cross-link-restraint.ts

@@ -12,8 +12,6 @@ import { CrossLinkRestraintRepresentationProvider } from '../../../../../mol-mod
 import { CrossLinkColorThemeProvider } from '../../../../../mol-model-props/integrative/cross-link-restraint/color';
 import { CrossLinkRestraint as _CrossLinkRestraint } from '../../../../../mol-model-props/integrative/cross-link-restraint/property';
 
-const Tag = _CrossLinkRestraint.Tag
-
 export const CrossLinkRestraint = PluginBehavior.create<{ }>({
     name: 'integrative-cross-link-restraint',
     category: 'custom-props',
@@ -24,14 +22,14 @@ export const CrossLinkRestraint = PluginBehavior.create<{ }>({
         register(): void {
             this.provider.formatRegistry.add('mmCIF', crossLinkRestraintFromMmcif)
 
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(Tag.CrossLinkRestraint, CrossLinkColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(CrossLinkColorThemeProvider)
             this.ctx.structureRepresentation.registry.add(CrossLinkRestraintRepresentationProvider)
         }
 
         unregister() {
             this.provider.formatRegistry.remove('mmCIF')
 
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(Tag.CrossLinkRestraint)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(CrossLinkColorThemeProvider)
             this.ctx.structureRepresentation.registry.remove(CrossLinkRestraintRepresentationProvider)
         }
     }

+ 2 - 2
src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts

@@ -46,7 +46,7 @@ export const PDBeStructureQualityReport = PluginBehavior.create<{ autoAttach: bo
             this.ctx.customModelProperties.register(this.provider, false);
             this.ctx.managers.lociLabels.addProvider(this.labelPDBeValidation);
 
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add('pdbe-structure-quality-report', StructureQualityReportColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(StructureQualityReportColorThemeProvider)
         }
 
         update(p: { autoAttach: boolean, showTooltip: boolean }) {
@@ -60,7 +60,7 @@ export const PDBeStructureQualityReport = PluginBehavior.create<{ autoAttach: bo
         unregister() {
             this.ctx.customModelProperties.unregister(StructureQualityReportProvider.descriptor.name);
             this.ctx.managers.lociLabels.removeProvider(this.labelPDBeValidation);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove('pdbe-structure-quality-report')
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(StructureQualityReportColorThemeProvider)
         }
     },
     params: () => ({

+ 2 - 2
src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts

@@ -29,7 +29,7 @@ export const RCSBAssemblySymmetry = PluginBehavior.create<{ autoAttach: boolean
         register(): void {
             this.ctx.state.dataState.actions.add(InitAssemblySymmetry3D)
             this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(Tag.Cluster, AssemblySymmetryClusterColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(AssemblySymmetryClusterColorThemeProvider)
         }
 
         update(p: { autoAttach: boolean }) {
@@ -42,7 +42,7 @@ export const RCSBAssemblySymmetry = PluginBehavior.create<{ autoAttach: boolean
         unregister() {
             this.ctx.state.dataState.actions.remove(InitAssemblySymmetry3D)
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(Tag.Cluster)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(AssemblySymmetryClusterColorThemeProvider)
         }
     },
     params: () => ({

+ 6 - 8
src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts

@@ -16,8 +16,6 @@ import { DensityFitColorThemeProvider } from '../../../../../mol-model-props/rcs
 import { cantorPairing } from '../../../../../mol-data/util';
 import { DefaultQueryRuntimeTable } from '../../../../../mol-script/runtime/query/compiler';
 
-const Tag = ValidationReport.Tag
-
 export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean, showTooltip: boolean }>({
     name: 'rcsb-validation-report-prop',
     category: 'custom-props',
@@ -44,9 +42,9 @@ export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean,
 
             this.ctx.managers.lociLabels.addProvider(this.label);
 
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(Tag.DensityFit, DensityFitColorThemeProvider)
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(Tag.GeometryQuality, GeometryQualityColorThemeProvider)
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(Tag.RandomCoilIndex, RandomCoilIndexColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(DensityFitColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(GeometryQualityColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(RandomCoilIndexColorThemeProvider)
 
             this.ctx.structureRepresentation.registry.add(ClashesRepresentationProvider)
         }
@@ -67,9 +65,9 @@ export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean,
 
             this.ctx.managers.lociLabels.removeProvider(this.label);
 
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(Tag.DensityFit)
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(Tag.GeometryQuality)
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(Tag.RandomCoilIndex)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(DensityFitColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(GeometryQualityColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(RandomCoilIndexColorThemeProvider)
 
             this.ctx.structureRepresentation.registry.remove(ClashesRepresentationProvider)
         }

+ 6 - 6
src/mol-plugin/behavior/dynamic/selection/structure-representation-interaction.ts

@@ -48,12 +48,12 @@ const StructureRepresentationInteractionParams = (plugin: PluginContext) => {
         }),
         nciParams: PD.Group(reprParams, {
             label: 'Non-covalent Int.',
-            customDefault: createStructureRepresentationParams(plugin, void 0, { type: 'ball-and-stick', color: 'element-symbol', size: 'uniform' })
-            // customDefault: createStructureRepresentationParams(plugin, void 0, {
-            //     type: InteractionsRepresentationProvider,
-            //     color: InteractionTypeColorThemeProvider,
-            //     size: BuiltInSizeThemes.uniform
-            // })
+            // customDefault: createStructureRepresentationParams(plugin, void 0, { type: 'ball-and-stick', color: 'element-symbol', size: 'uniform' })
+            customDefault: createStructureRepresentationParams(plugin, void 0, {
+                type: InteractionsRepresentationProvider,
+                color: InteractionTypeColorThemeProvider,
+                size: BuiltInSizeThemes.uniform
+            })
         })
     };
 }

+ 1 - 1
src/mol-repr/structure/registry.ts

@@ -24,7 +24,7 @@ export class StructureRepresentationRegistry extends RepresentationRegistry<Stru
     constructor() {
         super()
         objectForEach(BuiltInStructureRepresentations, (p, k) => {
-            if (p.name !== k) throw new Error('Fix BuiltInStructureRepresentations to have matching names.');
+            if (p.name !== k) throw new Error(`Fix BuiltInStructureRepresentations to have matching names. ${p.name} ${k}`);
             this.add(p as any)
         })
     }

+ 1 - 1
src/mol-repr/volume/registry.ts

@@ -14,7 +14,7 @@ export class VolumeRepresentationRegistry extends RepresentationRegistry<VolumeD
         super()
         Object.keys(BuiltInVolumeRepresentations).forEach(name => {
             objectForEach(BuiltInVolumeRepresentations, (p, k) => {
-                if (p.name !== k) throw new Error('Fix BuiltInVolumeRepresentations to have matching names.');
+                if (p.name !== k) throw new Error(`Fix BuiltInVolumeRepresentations to have matching names. ${p.name} ${k}`);
                 this.add(p as any)
             })
         })

+ 4 - 2
src/mol-theme/color.ts

@@ -70,8 +70,8 @@ namespace ColorTheme {
         return themeA.contextHash === themeB.contextHash && themeA.factory === themeB.factory && deepEqual(themeA.props, themeB.props)
     }
 
-    export interface Provider<P extends PD.Params = any> extends ThemeProvider<ColorTheme<P>, P> { }
-    export const EmptyProvider: Provider<{}> = { label: '', category: '', factory: EmptyFactory, getParams: () => ({}), defaultValues: {}, isApplicable: () => true }
+    export interface Provider<P extends PD.Params = any, Id extends string = string> extends ThemeProvider<ColorTheme<P>, P, Id> { }
+    export const EmptyProvider: Provider<{}> = { name: '', label: '', category: '', factory: EmptyFactory, getParams: () => ({}), defaultValues: {}, isApplicable: () => true }
 
     export type Registry = ThemeRegistry<ColorTheme<any>>
     export function createRegistry() {
@@ -81,6 +81,8 @@ namespace ColorTheme {
     export type ParamValues<C extends ColorTheme.Provider<any>> = C extends ColorTheme.Provider<infer P> ? PD.Values<P> : never
 }
 
+export function ColorThemeProvider<P extends PD.Params, Id extends string>(p: ColorTheme.Provider<P, Id>): ColorTheme.Provider<P, Id> { return p; }
+
 export const BuiltInColorThemes = {
     'carbohydrate-symbol': CarbohydrateSymbolColorThemeProvider,
     'chain-id': ChainIdColorThemeProvider,

+ 2 - 1
src/mol-theme/color/carbohydrate-symbol.ts

@@ -60,7 +60,8 @@ export function CarbohydrateSymbolColorTheme(ctx: ThemeDataContext, props: PD.Va
     }
 }
 
-export const CarbohydrateSymbolColorThemeProvider: ColorTheme.Provider<CarbohydrateSymbolColorThemeParams> = {
+export const CarbohydrateSymbolColorThemeProvider: ColorTheme.Provider<CarbohydrateSymbolColorThemeParams, 'carbohydrate-symbol'> = {
+    name: 'carbohydrate-symbol',
     label: 'Carbohydrate Symbol',
     category: ColorTheme.Category.Residue,
     factory: CarbohydrateSymbolColorTheme,

+ 2 - 1
src/mol-theme/color/chain-id.ts

@@ -117,7 +117,8 @@ export function ChainIdColorTheme(ctx: ThemeDataContext, props: PD.Values<ChainI
     }
 }
 
-export const ChainIdColorThemeProvider: ColorTheme.Provider<ChainIdColorThemeParams> = {
+export const ChainIdColorThemeProvider: ColorTheme.Provider<ChainIdColorThemeParams, 'chain-id'> = {
+    name: 'chain-id',
     label: 'Chain Id',
     category: ColorTheme.Category.Chain,
     factory: ChainIdColorTheme,

+ 2 - 1
src/mol-theme/color/element-index.ts

@@ -71,7 +71,8 @@ export function ElementIndexColorTheme(ctx: ThemeDataContext, props: PD.Values<E
     }
 }
 
-export const ElementIndexColorThemeProvider: ColorTheme.Provider<ElementIndexColorThemeParams> = {
+export const ElementIndexColorThemeProvider: ColorTheme.Provider<ElementIndexColorThemeParams, 'element-index'> = {
+    name: 'element-index',
     label: 'Element Index',
     category: ColorTheme.Category.Atom,
     factory: ElementIndexColorTheme,

+ 2 - 1
src/mol-theme/color/element-symbol.ts

@@ -67,7 +67,8 @@ export function ElementSymbolColorTheme(ctx: ThemeDataContext, props: PD.Values<
     }
 }
 
-export const ElementSymbolColorThemeProvider: ColorTheme.Provider<ElementSymbolColorThemeParams> = {
+export const ElementSymbolColorThemeProvider: ColorTheme.Provider<ElementSymbolColorThemeParams, 'element-symbol'> = {
+    name: 'element-symbol',
     label: 'Element Symbol',
     category: ColorTheme.Category.Atom,
     factory: ElementSymbolColorTheme,

+ 2 - 1
src/mol-theme/color/entity-source.ts

@@ -173,7 +173,8 @@ export function EntitySourceColorTheme(ctx: ThemeDataContext, props: PD.Values<E
     }
 }
 
-export const EntitySourceColorThemeProvider: ColorTheme.Provider<EntitySourceColorThemeParams> = {
+export const EntitySourceColorThemeProvider: ColorTheme.Provider<EntitySourceColorThemeParams, 'entity-source'> = {
+    name: 'entity-source',
     label: 'Entity Source',
     category: ColorTheme.Category.Chain,
     factory: EntitySourceColorTheme,

+ 2 - 1
src/mol-theme/color/hydrophobicity.ts

@@ -92,7 +92,8 @@ export function HydrophobicityColorTheme(ctx: ThemeDataContext, props: PD.Values
     }
 }
 
-export const HydrophobicityColorThemeProvider: ColorTheme.Provider<HydrophobicityColorThemeParams> = {
+export const HydrophobicityColorThemeProvider: ColorTheme.Provider<HydrophobicityColorThemeParams, 'hydrophobicity'> = {
+    name: 'hydrophobicity',
     label: 'Hydrophobicity',
     category: ColorTheme.Category.Residue,
     factory: HydrophobicityColorTheme,

+ 2 - 1
src/mol-theme/color/illustrative.ts

@@ -74,7 +74,8 @@ export function IllustrativeColorTheme(ctx: ThemeDataContext, props: PD.Values<I
     }
 }
 
-export const IllustrativeColorThemeProvider: ColorTheme.Provider<IllustrativeColorThemeParams> = {
+export const IllustrativeColorThemeProvider: ColorTheme.Provider<IllustrativeColorThemeParams, 'illustrative'> = {
+    name: 'illustrative',
     label: 'Illustrative',
     category: ColorTheme.Category.Misc,
     factory: IllustrativeColorTheme,

+ 2 - 1
src/mol-theme/color/model-index.ts

@@ -64,7 +64,8 @@ export function ModelIndexColorTheme(ctx: ThemeDataContext, props: PD.Values<Mod
     }
 }
 
-export const ModelIndexColorThemeProvider: ColorTheme.Provider<ModelIndexColorThemeParams> = {
+export const ModelIndexColorThemeProvider: ColorTheme.Provider<ModelIndexColorThemeParams, 'model-index'> = {
+    name: 'model-index',
     label: 'Model Index',
     category: ColorTheme.Category.Chain,
     factory: ModelIndexColorTheme,

+ 2 - 1
src/mol-theme/color/molecule-type.ts

@@ -76,7 +76,8 @@ export function MoleculeTypeColorTheme(ctx: ThemeDataContext, props: PD.Values<M
     }
 }
 
-export const MoleculeTypeColorThemeProvider: ColorTheme.Provider<MoleculeTypeColorThemeParams> = {
+export const MoleculeTypeColorThemeProvider: ColorTheme.Provider<MoleculeTypeColorThemeParams, 'molecule-type'> = {
+    name: 'molecule-type',
     label: 'Molecule Type',
     category: ColorTheme.Category.Residue,
     factory: MoleculeTypeColorTheme,

+ 2 - 1
src/mol-theme/color/occupancy.ts

@@ -58,7 +58,8 @@ export function OccupancyColorTheme(ctx: ThemeDataContext, props: PD.Values<Occu
     }
 }
 
-export const OccupancyColorThemeProvider: ColorTheme.Provider<OccupancyColorThemeParams> = {
+export const OccupancyColorThemeProvider: ColorTheme.Provider<OccupancyColorThemeParams, 'occupancy'> = {
+    name: 'occupancy',
     label: 'Occupancy',
     category: ColorTheme.Category.Atom,
     factory: OccupancyColorTheme,

+ 2 - 1
src/mol-theme/color/operator-hkl.ts

@@ -117,7 +117,8 @@ export function OperatorHklColorTheme(ctx: ThemeDataContext, props: PD.Values<Op
     }
 }
 
-export const OperatorHklColorThemeProvider: ColorTheme.Provider<OperatorHklColorThemeParams> = {
+export const OperatorHklColorThemeProvider: ColorTheme.Provider<OperatorHklColorThemeParams, 'operator-hkl'> = {
+    name: 'operator-hkl',
     label: 'Operator HKL',
     category: ColorTheme.Category.Symmetry,
     factory: OperatorHklColorTheme,

+ 2 - 1
src/mol-theme/color/operator-name.ts

@@ -83,7 +83,8 @@ export function OperatorNameColorTheme(ctx: ThemeDataContext, props: PD.Values<O
     }
 }
 
-export const OperatorNameColorThemeProvider: ColorTheme.Provider<OperatorNameColorThemeParams> = {
+export const OperatorNameColorThemeProvider: ColorTheme.Provider<OperatorNameColorThemeParams, 'operator-name'> = {
+    name: 'operator-name',
     label: 'Operator Name',
     category: ColorTheme.Category.Symmetry,
     factory: OperatorNameColorTheme,

+ 2 - 1
src/mol-theme/color/polymer-id.ts

@@ -126,7 +126,8 @@ export function PolymerIdColorTheme(ctx: ThemeDataContext, props: PD.Values<Poly
     }
 }
 
-export const PolymerIdColorThemeProvider: ColorTheme.Provider<PolymerIdColorThemeParams> = {
+export const PolymerIdColorThemeProvider: ColorTheme.Provider<PolymerIdColorThemeParams, 'polymer-id'> = {
+    name: 'polymer-id',
     label: 'Polymer Chain Id',
     category: ColorTheme.Category.Chain,
     factory: PolymerIdColorTheme,

+ 2 - 1
src/mol-theme/color/polymer-index.ts

@@ -86,7 +86,8 @@ export function PolymerIndexColorTheme(ctx: ThemeDataContext, props: PD.Values<P
     }
 }
 
-export const PolymerIndexColorThemeProvider: ColorTheme.Provider<PolymerIndexColorThemeParams> = {
+export const PolymerIndexColorThemeProvider: ColorTheme.Provider<PolymerIndexColorThemeParams, 'polymer-index'> = {
+    name: 'polymer-index',
     label: 'Polymer Chain Instance',
     category: ColorTheme.Category.Chain,
     factory: PolymerIndexColorTheme,

+ 2 - 1
src/mol-theme/color/residue-name.ts

@@ -128,7 +128,8 @@ export function ResidueNameColorTheme(ctx: ThemeDataContext, props: PD.Values<Re
     }
 }
 
-export const ResidueNameColorThemeProvider: ColorTheme.Provider<ResidueNameColorThemeParams> = {
+export const ResidueNameColorThemeProvider: ColorTheme.Provider<ResidueNameColorThemeParams, 'residue-name'> = {
+    name: 'residue-name',
     label: 'Residue Name',
     category: ColorTheme.Category.Residue,
     factory: ResidueNameColorTheme,

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

@@ -111,7 +111,8 @@ export function SecondaryStructureColorTheme(ctx: ThemeDataContext, props: PD.Va
     }
 }
 
-export const SecondaryStructureColorThemeProvider: ColorTheme.Provider<SecondaryStructureColorThemeParams> = {
+export const SecondaryStructureColorThemeProvider: ColorTheme.Provider<SecondaryStructureColorThemeParams, 'secondary-structure'> = {
+    name: 'secondary-structure',
     label: 'Secondary Structure',
     category: ColorTheme.Category.Residue,
     factory: SecondaryStructureColorTheme,

+ 2 - 1
src/mol-theme/color/sequence-id.ts

@@ -99,7 +99,8 @@ export function SequenceIdColorTheme(ctx: ThemeDataContext, props: PD.Values<Seq
     }
 }
 
-export const SequenceIdColorThemeProvider: ColorTheme.Provider<SequenceIdColorThemeParams> = {
+export const SequenceIdColorThemeProvider: ColorTheme.Provider<SequenceIdColorThemeParams, 'sequence-id'> = {
+    name: 'sequence-id',
     label: 'Sequence Id',
     category: ColorTheme.Category.Residue,
     factory: SequenceIdColorTheme,

+ 2 - 1
src/mol-theme/color/shape-group.ts

@@ -35,7 +35,8 @@ export function ShapeGroupColorTheme(ctx: ThemeDataContext, props: PD.Values<Sha
     }
 }
 
-export const ShapeGroupColorThemeProvider: ColorTheme.Provider<ShapeGroupColorThemeParams> = {
+export const ShapeGroupColorThemeProvider: ColorTheme.Provider<ShapeGroupColorThemeParams, 'shape-group'> = {
+    name: 'shape-group',
     label: 'Shape Group',
     category: ColorTheme.Category.Misc,
     factory: ShapeGroupColorTheme,

+ 2 - 1
src/mol-theme/color/uncertainty.ts

@@ -62,7 +62,8 @@ export function UncertaintyColorTheme(ctx: ThemeDataContext, props: PD.Values<Un
     }
 }
 
-export const UncertaintyColorThemeProvider: ColorTheme.Provider<UncertaintyColorThemeParams> = {
+export const UncertaintyColorThemeProvider: ColorTheme.Provider<UncertaintyColorThemeParams, 'uncertainty'> = {
+    name: 'uncertainty',
     label: 'Uncertainty/Disorder',
     category: ColorTheme.Category.Atom,
     factory: UncertaintyColorTheme,

+ 2 - 1
src/mol-theme/color/uniform.ts

@@ -35,7 +35,8 @@ export function UniformColorTheme(ctx: ThemeDataContext, props: PD.Values<Unifor
     }
 }
 
-export const UniformColorThemeProvider: ColorTheme.Provider<UniformColorThemeParams> = {
+export const UniformColorThemeProvider: ColorTheme.Provider<UniformColorThemeParams, 'uniform'> = {
+    name: 'uniform',
     label: 'Uniform',
     category: ColorTheme.Category.Misc,
     factory: UniformColorTheme,

+ 2 - 1
src/mol-theme/color/unit-index.ts

@@ -71,7 +71,8 @@ export function UnitIndexColorTheme(ctx: ThemeDataContext, props: PD.Values<Unit
     }
 }
 
-export const UnitIndexColorThemeProvider: ColorTheme.Provider<UnitIndexColorThemeParams> = {
+export const UnitIndexColorThemeProvider: ColorTheme.Provider<UnitIndexColorThemeParams, 'unit-index'> = {
+    name: 'unit-index',
     label: 'Chain Instance',
     category: ColorTheme.Category.Chain,
     factory: UnitIndexColorTheme,

+ 2 - 2
src/mol-theme/size.ts

@@ -31,8 +31,8 @@ namespace SizeTheme {
         return themeA.factory === themeB.factory && deepEqual(themeA.props, themeB.props)
     }
 
-    export interface Provider<P extends PD.Params = any> extends ThemeProvider<SizeTheme<P>, P> { }
-    export const EmptyProvider: Provider<{}> = { label: '', category: '', factory: EmptyFactory, getParams: () => ({}), defaultValues: {}, isApplicable: () => true }
+    export interface Provider<P extends PD.Params = any, Id extends string = string> extends ThemeProvider<SizeTheme<P>, P, Id> { }
+    export const EmptyProvider: Provider<{}> = { name: '', label: '', category: '', factory: EmptyFactory, getParams: () => ({}), defaultValues: {}, isApplicable: () => true }
 
     export type Registry = ThemeRegistry<SizeTheme<any>>
     export function createRegistry() {

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

@@ -56,7 +56,8 @@ export function PhysicalSizeTheme(ctx: ThemeDataContext, props: PD.Values<Physic
     }
 }
 
-export const PhysicalSizeThemeProvider: SizeTheme.Provider<PhysicalSizeThemeParams> = {
+export const PhysicalSizeThemeProvider: SizeTheme.Provider<PhysicalSizeThemeParams, 'physical'> = {
+    name: 'physical',
     label: 'Physical',
     category: '',
     factory: PhysicalSizeTheme,

+ 2 - 1
src/mol-theme/size/shape-group.ts

@@ -34,7 +34,8 @@ export function ShapeGroupSizeTheme(ctx: ThemeDataContext, props: PD.Values<Shap
     }
 }
 
-export const ShapeGroupSizeThemeProvider: SizeTheme.Provider<ShapeGroupSizeThemeParams> = {
+export const ShapeGroupSizeThemeProvider: SizeTheme.Provider<ShapeGroupSizeThemeParams, 'shape-group'> = {
+    name: 'shape-group',
     label: 'Shape Group',
     category: '',    
     factory: ShapeGroupSizeTheme,

+ 2 - 1
src/mol-theme/size/uncertainty.ts

@@ -52,7 +52,8 @@ export function UncertaintySizeTheme(ctx: ThemeDataContext, props: PD.Values<Unc
     }
 }
 
-export const UncertaintySizeThemeProvider: SizeTheme.Provider<UncertaintySizeThemeParams> = {
+export const UncertaintySizeThemeProvider: SizeTheme.Provider<UncertaintySizeThemeParams, 'uncertainty'> = {
+    name: 'uncertainty',
     label: 'Uncertainty/Disorder',
     category: '',
     factory: UncertaintySizeTheme,

+ 2 - 1
src/mol-theme/size/uniform.ts

@@ -30,7 +30,8 @@ export function UniformSizeTheme(ctx: ThemeDataContext, props: PD.Values<Uniform
     }
 }
 
-export const UniformSizeThemeProvider: SizeTheme.Provider<UniformSizeThemeParams> = {
+export const UniformSizeThemeProvider: SizeTheme.Provider<UniformSizeThemeParams, 'uniform'> = {
+    name: 'uniform',
     label: 'Uniform',
     category: '',
     factory: UniformSizeTheme,

+ 14 - 4
src/mol-theme/theme.ts

@@ -11,6 +11,7 @@ import { VolumeData } from '../mol-model/volume';
 import { ParamDefinition as PD } from '../mol-util/param-definition';
 import { Shape } from '../mol-model/shape';
 import { CustomProperty } from '../mol-model-props/common/custom-property';
+import { objectForEach } from '../mol-util/object';
 
 export interface ThemeRegistryContext {
     colorThemeRegistry: ColorTheme.Registry
@@ -64,7 +65,8 @@ namespace Theme {
 
 //
 
-export interface ThemeProvider<T extends ColorTheme<P> | SizeTheme<P>, P extends PD.Params> {
+export interface ThemeProvider<T extends ColorTheme<P> | SizeTheme<P>, P extends PD.Params, Id extends string = string> {
+    readonly name: Id
     readonly label: string
     readonly category: string
     readonly factory: (ctx: ThemeDataContext, props: PD.Values<P>) => T
@@ -91,7 +93,10 @@ export class ThemeRegistry<T extends ColorTheme<any> | SizeTheme<any>> {
     get types(): [string, string, string][] { return getTypes(this._list) }
 
     constructor(builtInThemes: { [k: string]: ThemeProvider<T, any> }, private emptyProvider: ThemeProvider<T, any>) {
-        Object.keys(builtInThemes).forEach(name => this.add(name, builtInThemes[name]))
+        objectForEach(builtInThemes, (p, k) => {
+            if (p.name !== k) throw new Error(`Fix build in themes to have matching names. ${p.name} ${k}`);
+            this.add(p as any)
+        })
     }
 
     private sort() {
@@ -103,14 +108,19 @@ export class ThemeRegistry<T extends ColorTheme<any> | SizeTheme<any>> {
         });
     }
 
-    add<P extends PD.Params>(name: string, provider: ThemeProvider<T, P>) {
+    add<P extends PD.Params>(provider: ThemeProvider<T, P>) {
+        if (this._map.has(provider.name)) {
+            throw new Error(`${provider.name} already registered.`);
+        }
+
+        const name = provider.name;
         this._list.push({ name, provider })
         this._map.set(name, provider)
         this._name.set(provider, name)
         this.sort();
     }
 
-    remove(name: string) {
+    remove(provider: ThemeProvider<T, any>) {
         this._list.splice(this._list.findIndex(e => e.name === name), 1)
         const p = this._map.get(name);
         if (p) {