cartoon.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /**
  2. * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { Structure, Unit } from '../../../mol-model/structure';
  7. import { Representation, RepresentationContext, RepresentationParamsGetter } from '../../../mol-repr/representation';
  8. import { ThemeRegistryContext } from '../../../mol-theme/theme';
  9. import { ParamDefinition as PD } from '../../../mol-util/param-definition';
  10. import { StructureRepresentation, StructureRepresentationProvider, StructureRepresentationStateBuilder } from '../representation';
  11. import { UnitsRepresentation } from '../units-representation';
  12. import { NucleotideBlockParams, NucleotideBlockVisual } from '../visual/nucleotide-block-mesh';
  13. import { NucleotideRingParams, NucleotideRingVisual } from '../visual/nucleotide-ring-mesh';
  14. import { PolymerDirectionParams, PolymerDirectionVisual } from '../visual/polymer-direction-wedge';
  15. import { PolymerGapParams, PolymerGapVisual } from '../visual/polymer-gap-cylinder';
  16. import { PolymerTraceParams, PolymerTraceVisual } from '../visual/polymer-trace-mesh';
  17. import { SecondaryStructureProvider } from '../../../mol-model-props/computed/secondary-structure';
  18. import { CustomProperty } from '../../../mol-model-props/common/custom-property';
  19. import { HelixOrientationProvider } from '../../../mol-model-props/computed/helix-orientation';
  20. const CartoonVisuals = {
  21. 'polymer-trace': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, PolymerTraceParams>) => UnitsRepresentation('Polymer trace mesh', ctx, getParams, PolymerTraceVisual),
  22. 'polymer-gap': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, PolymerGapParams>) => UnitsRepresentation('Polymer gap cylinder', ctx, getParams, PolymerGapVisual),
  23. 'nucleotide-block': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, NucleotideBlockParams>) => UnitsRepresentation('Nucleotide block mesh', ctx, getParams, NucleotideBlockVisual),
  24. 'nucleotide-ring': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, NucleotideRingParams>) => UnitsRepresentation('Nucleotide ring mesh', ctx, getParams, NucleotideRingVisual),
  25. 'direction-wedge': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, PolymerDirectionParams>) => UnitsRepresentation('Polymer direction wedge', ctx, getParams, PolymerDirectionVisual)
  26. };
  27. export const CartoonParams = {
  28. ...PolymerTraceParams,
  29. ...PolymerGapParams,
  30. ...NucleotideBlockParams,
  31. ...NucleotideRingParams,
  32. ...PolymerDirectionParams,
  33. sizeFactor: PD.Numeric(0.2, { min: 0, max: 10, step: 0.01 }),
  34. visuals: PD.MultiSelect(['polymer-trace', 'polymer-gap', 'nucleotide-block'], PD.objectToOptions(CartoonVisuals)),
  35. };
  36. export type CartoonParams = typeof CartoonParams
  37. export function getCartoonParams(ctx: ThemeRegistryContext, structure: Structure) {
  38. const params = PD.clone(CartoonParams);
  39. let hasNucleotides = false;
  40. let hasGaps = false;
  41. structure.units.forEach(u => {
  42. if (!hasNucleotides && Unit.isAtomic(u) && u.nucleotideElements.length) hasNucleotides = true;
  43. if (!hasGaps && u.gapElements.length) hasGaps = true;
  44. });
  45. params.visuals.defaultValue = ['polymer-trace'];
  46. if (hasNucleotides) params.visuals.defaultValue.push('nucleotide-block');
  47. if (hasGaps) params.visuals.defaultValue.push('polymer-gap');
  48. return params;
  49. }
  50. export type CartoonRepresentation = StructureRepresentation<CartoonParams>
  51. export function CartoonRepresentation(ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, CartoonParams>): CartoonRepresentation {
  52. return Representation.createMulti('Cartoon', ctx, getParams, StructureRepresentationStateBuilder, CartoonVisuals as unknown as Representation.Def<Structure, CartoonParams>);
  53. }
  54. export const CartoonRepresentationProvider = StructureRepresentationProvider({
  55. name: 'cartoon',
  56. label: 'Cartoon',
  57. description: 'Displays ribbons, planks, tubes smoothly following the trace atoms of polymers.',
  58. factory: CartoonRepresentation,
  59. getParams: getCartoonParams,
  60. defaultValues: PD.getDefaultValues(CartoonParams),
  61. defaultColorTheme: { name: 'chain-id' },
  62. defaultSizeTheme: { name: 'uniform' },
  63. isApplicable: (structure: Structure) => structure.polymerResidueCount > 0,
  64. ensureCustomProperties: {
  65. attach: async (ctx: CustomProperty.Context, structure: Structure) => {
  66. await SecondaryStructureProvider.attach(ctx, structure, void 0, true);
  67. for (const m of structure.models) {
  68. await HelixOrientationProvider.attach(ctx, m, void 0, true);
  69. }
  70. },
  71. detach: (data) => {
  72. SecondaryStructureProvider.ref(data, false);
  73. for (const m of data.models) {
  74. HelixOrientationProvider.ref(m, false);
  75. }
  76. }
  77. }
  78. });