-
Alexander Rose authoredAlexander Rose authored
secondary-structure.ts 5.33 KiB
/**
* Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Color, ColorMap } from 'mol-util/color';
import { StructureElement, Unit, Link, ElementIndex } from 'mol-model/structure';
import { Location } from 'mol-model/location';
import { ColorTheme } from '../color';
import { SecondaryStructureType, MoleculeType } from 'mol-model/structure/model/types';
import { getElementMoleculeType } from 'mol-model/structure/util';
import { ParamDefinition as PD } from 'mol-util/param-definition'
import { ThemeDataContext } from '../theme';
import { TableLegend } from 'mol-util/color/tables';
import { ComputedSecondaryStructure } from 'mol-model-props/computed/secondary-structure';
// from Jmol http://jmol.sourceforge.net/jscolors/ (shapely)
const SecondaryStructureColors = ColorMap({
'alphaHelix': 0xFF0080,
'threeTenHelix': 0xA00080,
'piHelix': 0x600080,
'betaTurn': 0x6080FF,
'betaStrand': 0xFFC800,
'coil': 0xFFFFFF,
'bend': 0x66D8C9 /* biting original color used 0x00FF00 */,
'turn': 0x00B266,
'dna': 0xAE00FE,
'rna': 0xFD0162,
'carbohydrate': 0xA6A6FA
})
const DefaultSecondaryStructureColor = Color(0x808080)
const Description = 'Assigns a color based on the type of secondary structure and basic molecule type.'
export const SecondaryStructureColorThemeParams = {}
export type SecondaryStructureColorThemeParams = typeof SecondaryStructureColorThemeParams
export function getSecondaryStructureColorThemeParams(ctx: ThemeDataContext) {
return SecondaryStructureColorThemeParams // TODO return copy
}
export function secondaryStructureColor(unit: Unit, element: ElementIndex, computedSecondaryStructure: ComputedSecondaryStructure.Property | undefined): Color {
let secStrucType = SecondaryStructureType.create(SecondaryStructureType.Flag.None)
if (Unit.isAtomic(unit)) {
secStrucType = unit.model.properties.secondaryStructure.type[unit.residueIndex[element]]
if (computedSecondaryStructure) {
const secondaryStructure = computedSecondaryStructure.map.get(unit.invariantId)
if (secondaryStructure) secStrucType = secondaryStructure.type[secondaryStructure.getIndex(unit.residueIndex[element])]
}
}
if (SecondaryStructureType.is(secStrucType, SecondaryStructureType.Flag.Helix)) {
if (SecondaryStructureType.is(secStrucType, SecondaryStructureType.Flag.Helix3Ten)) {
return SecondaryStructureColors.threeTenHelix
} else if (SecondaryStructureType.is(secStrucType, SecondaryStructureType.Flag.HelixPi)) {
return SecondaryStructureColors.piHelix
}
return SecondaryStructureColors.alphaHelix
} else if (SecondaryStructureType.is(secStrucType, SecondaryStructureType.Flag.Beta)) {
return SecondaryStructureColors.betaStrand
} else if (SecondaryStructureType.is(secStrucType, SecondaryStructureType.Flag.Bend)) {
return SecondaryStructureColors.bend
} else if (SecondaryStructureType.is(secStrucType, SecondaryStructureType.Flag.Turn)) {
return SecondaryStructureColors.turn
} else {
const moleculeType = getElementMoleculeType(unit, element)
if (moleculeType === MoleculeType.DNA) {
return SecondaryStructureColors.dna
} else if (moleculeType === MoleculeType.RNA) {
return SecondaryStructureColors.rna
} else if (moleculeType === MoleculeType.saccharide) {
return SecondaryStructureColors.carbohydrate
} else if (moleculeType === MoleculeType.protein) {
return SecondaryStructureColors.coil
}
}
return DefaultSecondaryStructureColor
}
export function SecondaryStructureColorTheme(ctx: ThemeDataContext, props: PD.Values<SecondaryStructureColorThemeParams>): ColorTheme<SecondaryStructureColorThemeParams> {
const computedSecondaryStructure = ctx.structure && ComputedSecondaryStructure.get(ctx.structure)
// use `computedSecondaryStructure.id` as context hash, when available
const contextHash = computedSecondaryStructure && computedSecondaryStructure.id
function color(location: Location): Color {
if (StructureElement.isLocation(location)) {
return secondaryStructureColor(location.unit, location.element, computedSecondaryStructure)
} else if (Link.isLocation(location)) {
return secondaryStructureColor(location.aUnit, location.aUnit.elements[location.aIndex], computedSecondaryStructure)
}
return DefaultSecondaryStructureColor
}
return {
factory: SecondaryStructureColorTheme,
granularity: 'group',
color,
props,
contextHash,
description: Description,
legend: TableLegend(Object.keys(SecondaryStructureColors).map(name => {
return [name, (SecondaryStructureColors as any)[name] as Color] as [string, Color]
}).concat([[ 'Other', DefaultSecondaryStructureColor ]]))
}
}
export const SecondaryStructureColorThemeProvider: ColorTheme.Provider<SecondaryStructureColorThemeParams> = {
label: 'Secondary Structure',
factory: SecondaryStructureColorTheme,
getParams: getSecondaryStructureColorThemeParams,
defaultValues: PD.getDefaultValues(SecondaryStructureColorThemeParams),
isApplicable: (ctx: ThemeDataContext) => !!ctx.structure
}