accessible-surface-area.ts 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /**
  2. * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
  5. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. import { ParamDefinition as PD } from '../../../mol-util/param-definition';
  8. import { Color, ColorScale } from '../../../mol-util/color';
  9. import { ThemeDataContext } from '../../../mol-theme/theme';
  10. import { ColorTheme, LocationColor } from '../../../mol-theme/color';
  11. import { Bond, StructureElement, Unit } from '../../../mol-model/structure';
  12. import { AccessibleSurfaceAreaProvider } from '../accessible-surface-area';
  13. import { AccessibleSurfaceArea } from '../accessible-surface-area/shrake-rupley';
  14. import { CustomProperty } from '../../common/custom-property';
  15. import { Location } from '../../../mol-model/location';
  16. import { hash2 } from '../../../mol-data/util';
  17. const DefaultColor = Color(0xFAFAFA);
  18. const Description = 'Assigns a color based on the relative accessible surface area of a residue.';
  19. export const AccessibleSurfaceAreaColorThemeParams = {
  20. list: PD.ColorList('rainbow', { presetKind: 'scale' })
  21. };
  22. export type AccessibleSurfaceAreaColorThemeParams = typeof AccessibleSurfaceAreaColorThemeParams
  23. export function getAccessibleSurfaceAreaColorThemeParams(ctx: ThemeDataContext) {
  24. return AccessibleSurfaceAreaColorThemeParams; // TODO return copy
  25. }
  26. export function AccessibleSurfaceAreaColorTheme(ctx: ThemeDataContext, props: PD.Values<AccessibleSurfaceAreaColorThemeParams>): ColorTheme<AccessibleSurfaceAreaColorThemeParams> {
  27. let color: LocationColor;
  28. const scale = ColorScale.create({
  29. listOrName: props.list.colors,
  30. minLabel: 'buried',
  31. maxLabel: 'exposed',
  32. domain: [0.0, 1.0]
  33. });
  34. const accessibleSurfaceArea = ctx.structure && AccessibleSurfaceAreaProvider.get(ctx.structure);
  35. const contextHash = accessibleSurfaceArea ? hash2(accessibleSurfaceArea.id, accessibleSurfaceArea.version) : -1;
  36. if (accessibleSurfaceArea?.value && ctx.structure) {
  37. const l = StructureElement.Location.create(ctx.structure);
  38. const asa = accessibleSurfaceArea.value;
  39. const getColor = (location: StructureElement.Location) => {
  40. const value = AccessibleSurfaceArea.getNormalizedValue(location, asa);
  41. return value === -1 ? DefaultColor : scale.color(value);
  42. };
  43. color = (location: Location): Color => {
  44. if (StructureElement.Location.is(location) && Unit.isAtomic(location.unit)) {
  45. return getColor(location);
  46. } else if (Bond.isLocation(location)) {
  47. l.unit = location.aUnit;
  48. l.element = location.aUnit.elements[location.aIndex];
  49. return getColor(l);
  50. }
  51. return DefaultColor;
  52. };
  53. } else {
  54. color = () => DefaultColor;
  55. }
  56. return {
  57. factory: AccessibleSurfaceAreaColorTheme,
  58. granularity: 'group',
  59. preferSmoothing: true,
  60. color,
  61. props,
  62. contextHash,
  63. description: Description,
  64. legend: scale ? scale.legend : undefined
  65. };
  66. }
  67. export const AccessibleSurfaceAreaColorThemeProvider: ColorTheme.Provider<AccessibleSurfaceAreaColorThemeParams, 'accessible-surface-area'> = {
  68. name: 'accessible-surface-area',
  69. label: 'Accessible Surface Area',
  70. category: ColorTheme.Category.Residue,
  71. factory: AccessibleSurfaceAreaColorTheme,
  72. getParams: getAccessibleSurfaceAreaColorThemeParams,
  73. defaultValues: PD.getDefaultValues(AccessibleSurfaceAreaColorThemeParams),
  74. isApplicable: (ctx: ThemeDataContext) => !!ctx.structure,
  75. ensureCustomProperties: {
  76. attach: (ctx: CustomProperty.Context, data: ThemeDataContext) => data.structure ? AccessibleSurfaceAreaProvider.attach(ctx, data.structure, void 0, true) : Promise.resolve(),
  77. detach: (data) => data.structure && AccessibleSurfaceAreaProvider.ref(data.structure, false)
  78. }
  79. };