cartoon.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /**
  2. * Copyright (c) 2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { Color } from '../../mol-util/color';
  7. import { Location } from '../../mol-model/location';
  8. import type { ColorTheme } from '../color';
  9. import { ParamDefinition as PD } from '../../mol-util/param-definition';
  10. import { ThemeDataContext } from '../theme';
  11. import { ChainIdColorTheme, ChainIdColorThemeParams } from './chain-id';
  12. import { UniformColorTheme, UniformColorThemeParams } from './uniform';
  13. import { assertUnreachable } from '../../mol-util/type-helpers';
  14. import { EntityIdColorTheme, EntityIdColorThemeParams } from './entity-id';
  15. import { MoleculeTypeColorTheme, MoleculeTypeColorThemeParams } from './molecule-type';
  16. import { EntitySourceColorTheme, EntitySourceColorThemeParams } from './entity-source';
  17. import { ModelIndexColorTheme, ModelIndexColorThemeParams } from './model-index';
  18. import { StructureIndexColorTheme, StructureIndexColorThemeParams } from './structure-index';
  19. import { ColorThemeCategory } from './categories';
  20. import { ResidueNameColorTheme, ResidueNameColorThemeParams } from './residue-name';
  21. import { ScaleLegend, TableLegend } from '../../mol-util/legend';
  22. import { SecondaryStructureColorTheme, SecondaryStructureColorThemeParams } from './secondary-structure';
  23. import { ElementSymbolColorTheme, ElementSymbolColorThemeParams } from './element-symbol';
  24. const Description = 'Uses separate themes for coloring mainchain and sidechain visuals.';
  25. export const CartoonColorThemeParams = {
  26. mainchain: PD.MappedStatic('molecule-type', {
  27. uniform: PD.Group(UniformColorThemeParams),
  28. 'chain-id': PD.Group(ChainIdColorThemeParams),
  29. 'entity-id': PD.Group(EntityIdColorThemeParams),
  30. 'entity-source': PD.Group(EntitySourceColorThemeParams),
  31. 'molecule-type': PD.Group(MoleculeTypeColorThemeParams),
  32. 'model-index': PD.Group(ModelIndexColorThemeParams),
  33. 'structure-index': PD.Group(StructureIndexColorThemeParams),
  34. 'secondary-structure': PD.Group(SecondaryStructureColorThemeParams),
  35. }),
  36. sidechain: PD.MappedStatic('residue-name', {
  37. uniform: PD.Group(UniformColorThemeParams),
  38. 'residue-name': PD.Group(ResidueNameColorThemeParams),
  39. 'element-symbol': PD.Group(ElementSymbolColorThemeParams),
  40. }),
  41. };
  42. export type CartoonColorThemeParams = typeof CartoonColorThemeParams
  43. export function getCartoonColorThemeParams(ctx: ThemeDataContext) {
  44. const params = PD.clone(CartoonColorThemeParams);
  45. return params;
  46. }
  47. type CartoonColorThemeProps = PD.Values<CartoonColorThemeParams>
  48. function getMainchainTheme(ctx: ThemeDataContext, props: CartoonColorThemeProps['mainchain']) {
  49. switch (props.name) {
  50. case 'uniform': return UniformColorTheme(ctx, props.params);
  51. case 'chain-id': return ChainIdColorTheme(ctx, props.params);
  52. case 'entity-id': return EntityIdColorTheme(ctx, props.params);
  53. case 'entity-source': return EntitySourceColorTheme(ctx, props.params);
  54. case 'molecule-type': return MoleculeTypeColorTheme(ctx, props.params);
  55. case 'model-index': return ModelIndexColorTheme(ctx, props.params);
  56. case 'structure-index': return StructureIndexColorTheme(ctx, props.params);
  57. case 'secondary-structure': return SecondaryStructureColorTheme(ctx, props.params);
  58. default: assertUnreachable(props);
  59. }
  60. }
  61. function getSidechainTheme(ctx: ThemeDataContext, props: CartoonColorThemeProps['sidechain']) {
  62. switch (props.name) {
  63. case 'uniform': return UniformColorTheme(ctx, props.params);
  64. case 'residue-name': return ResidueNameColorTheme(ctx, props.params);
  65. case 'element-symbol': return ElementSymbolColorTheme(ctx, props.params);
  66. default: assertUnreachable(props);
  67. }
  68. }
  69. export function CartoonColorTheme(ctx: ThemeDataContext, props: PD.Values<CartoonColorThemeParams>): ColorTheme<CartoonColorThemeParams> {
  70. const mainchain = getMainchainTheme(ctx, props.mainchain);
  71. const sidechain = getSidechainTheme(ctx, props.sidechain);
  72. function color(location: Location, isSecondary: boolean): Color {
  73. return isSecondary ? mainchain.color(location, false) : sidechain.color(location, false);
  74. }
  75. let legend: ScaleLegend | TableLegend | undefined = mainchain.legend;
  76. if (mainchain.legend?.kind === 'table-legend' && sidechain.legend?.kind === 'table-legend') {
  77. legend = {
  78. kind: 'table-legend',
  79. table: [...mainchain.legend.table, ...sidechain.legend.table]
  80. };
  81. }
  82. return {
  83. factory: CartoonColorTheme,
  84. granularity: 'group',
  85. preferSmoothing: false,
  86. color,
  87. props,
  88. description: Description,
  89. legend,
  90. };
  91. }
  92. export const CartoonColorThemeProvider: ColorTheme.Provider<CartoonColorThemeParams, 'cartoon'> = {
  93. name: 'cartoon',
  94. label: 'Cartoon',
  95. category: ColorThemeCategory.Misc,
  96. factory: CartoonColorTheme,
  97. getParams: getCartoonColorThemeParams,
  98. defaultValues: PD.getDefaultValues(CartoonColorThemeParams),
  99. isApplicable: (ctx: ThemeDataContext) => !!ctx.structure
  100. };