Skip to content
Snippets Groups Projects
Commit 5d5fd002 authored by Alexander Rose's avatar Alexander Rose
Browse files

added operator name & hkl color themes

parent c88693df
No related branches found
No related tags found
No related merge requests found
......@@ -31,6 +31,8 @@ import { IllustrativeColorThemeProvider } from './color/illustrative';
import { HydrophobicityColorThemeProvider } from './color/hydrophobicity';
import { ModelIndexColorThemeProvider } from './color/model-index';
import { OccupancyColorThemeProvider } from './color/occupancy';
import { OperatorNameColorThemeProvider } from './color/operator-name';
import { OperatorHklColorThemeProvider } from './color/operator-hkl';
export type LocationColor = (location: Location, isSecondary: boolean) => Color
......@@ -83,6 +85,8 @@ export const BuiltInColorThemes = {
'model-index': ModelIndexColorThemeProvider,
'molecule-type': MoleculeTypeColorThemeProvider,
'occupancy': OccupancyColorThemeProvider,
'operator-hkl': OperatorHklColorThemeProvider,
'operator-name': OperatorNameColorThemeProvider,
'polymer-id': PolymerIdColorThemeProvider,
'polymer-index': PolymerIndexColorThemeProvider,
'residue-name': ResidueNameColorThemeProvider,
......
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Color } from '../../mol-util/color';
import { StructureElement, Link, Structure } from '../../mol-model/structure';
import { Location } from '../../mol-model/location';
import { ColorTheme, LocationColor } from '../color';
import { ParamDefinition as PD } from '../../mol-util/param-definition'
import { ThemeDataContext } from '../theme';
import { getPaletteParams, getPalette } from '../../mol-util/color/palette';
import { ScaleLegend, TableLegend } from '../../mol-util/legend';
import { Vec3 } from '../../mol-math/linear-algebra';
import { integerDigitCount } from '../../mol-util/number';
const DefaultColor = Color(0xCCCCCC)
const Description = `Assigns a color based on the operator HKL value of a transformed chain.`
export const OperatorHklColorThemeParams = {
...getPaletteParams({ type: 'set', setList: 'set-3' }),
}
export type OperatorHklColorThemeParams = typeof OperatorHklColorThemeParams
export function getOperatorHklColorThemeParams(ctx: ThemeDataContext) {
const params = PD.clone(OperatorHklColorThemeParams)
if (ctx.structure) {
if (getOperatorHklSerialMap(ctx.structure.root).map.size > 12) {
params.palette.defaultValue.name = 'scale'
params.palette.defaultValue.params = {
...params.palette.defaultValue.params,
list: 'red-yellow-blue'
}
}
}
return params
}
const hklOffset = 10000
function hklKey(hkl: Vec3) {
return hkl.map(v => `${v + hklOffset}`.padStart(5, '0')).join('')
}
function hklKeySplit(key: string) {
const len = integerDigitCount(hklOffset, 0)
const h = parseInt(key.substr(0, len))
const k = parseInt(key.substr(len, len))
const l = parseInt(key.substr(len + len, len))
return [ h - hklOffset, k - hklOffset, l - hklOffset ] as Vec3
}
function formatHkl(hkl: Vec3) {
return hkl.map(v => v + 5).join('')
}
function getOperatorHklSerialMap(structure: Structure) {
const map = new Map<string, number>()
const set = new Set<string>()
for (let i = 0, il = structure.units.length; i < il; ++i) {
const k = hklKey(structure.units[i].conformation.operator.hkl)
set.add(k)
}
const arr = Array.from(set).sort()
arr.forEach(k => map.set(k, map.size))
const min = hklKeySplit(arr[0])
const max = hklKeySplit(arr[arr.length - 1])
return { min, max, map }
}
export function OperatorHklColorTheme(ctx: ThemeDataContext, props: PD.Values<OperatorHklColorThemeParams>): ColorTheme<OperatorHklColorThemeParams> {
let color: LocationColor
let legend: ScaleLegend | TableLegend | undefined
if (ctx.structure) {
const { min, max, map } = getOperatorHklSerialMap(ctx.structure.root)
const labelTable: string[] = []
map.forEach((v, k) => {
const i = v % map.size
const label = formatHkl(hklKeySplit(k))
if (labelTable[i] === undefined) labelTable[i] = label
else labelTable[i] += `, ${label}`
})
props.palette.params.minLabel = formatHkl(min)
props.palette.params.maxLabel = formatHkl(max)
props.palette.params.valueLabel = (i: number) => labelTable[i]
const palette = getPalette(map.size, props)
legend = palette.legend
color = (location: Location): Color => {
let serial: number | undefined = undefined
if (StructureElement.Location.is(location)) {
const k = hklKey(location.unit.conformation.operator.hkl)
serial = map.get(k)
} else if (Link.isLocation(location)) {
const k = hklKey(location.aUnit.conformation.operator.hkl)
serial = map.get(k)
}
return serial === undefined ? DefaultColor : palette.color(serial)
}
} else {
color = () => DefaultColor
}
return {
factory: OperatorHklColorTheme,
granularity: 'instance',
color,
props,
description: Description,
legend
}
}
export const OperatorHklColorThemeProvider: ColorTheme.Provider<OperatorHklColorThemeParams> = {
label: 'Operator HKL',
factory: OperatorHklColorTheme,
getParams: getOperatorHklColorThemeParams,
defaultValues: PD.getDefaultValues(OperatorHklColorThemeParams),
isApplicable: (ctx: ThemeDataContext) => !!ctx.structure
}
\ No newline at end of file
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Color } from '../../mol-util/color';
import { StructureElement, Link, Structure } from '../../mol-model/structure';
import { Location } from '../../mol-model/location';
import { ColorTheme, LocationColor } from '../color';
import { ParamDefinition as PD } from '../../mol-util/param-definition'
import { ThemeDataContext } from '../theme';
import { getPaletteParams, getPalette } from '../../mol-util/color/palette';
import { ScaleLegend, TableLegend } from '../../mol-util/legend';
const DefaultColor = Color(0xCCCCCC)
const Description = `Assigns a color based on the operator name of a transformed chain.`
export const OperatorNameColorThemeParams = {
...getPaletteParams({ type: 'set', setList: 'set-3' }),
}
export type OperatorNameColorThemeParams = typeof OperatorNameColorThemeParams
export function getOperatorNameColorThemeParams(ctx: ThemeDataContext) {
const params = PD.clone(OperatorNameColorThemeParams)
if (ctx.structure) {
if (getOperatorNameSerialMap(ctx.structure.root).size > 12) {
params.palette.defaultValue.name = 'scale'
params.palette.defaultValue.params = {
...params.palette.defaultValue.params,
list: 'red-yellow-blue'
}
}
}
return params
}
function getOperatorNameSerialMap(structure: Structure) {
const map = new Map<string, number>()
for (let i = 0, il = structure.units.length; i < il; ++i) {
const name = structure.units[i].conformation.operator.name
if (!map.has(name)) map.set(name, map.size)
}
return map
}
export function OperatorNameColorTheme(ctx: ThemeDataContext, props: PD.Values<OperatorNameColorThemeParams>): ColorTheme<OperatorNameColorThemeParams> {
let color: LocationColor
let legend: ScaleLegend | TableLegend | undefined
if (ctx.structure) {
const operatorNameSerialMap = getOperatorNameSerialMap(ctx.structure.root)
const labelTable = Array.from(operatorNameSerialMap.keys())
props.palette.params.valueLabel = (i: number) => labelTable[i]
const palette = getPalette(operatorNameSerialMap.size, props)
legend = palette.legend
color = (location: Location): Color => {
let serial: number | undefined = undefined
if (StructureElement.Location.is(location)) {
const name = location.unit.conformation.operator.name
serial = operatorNameSerialMap.get(name)
} else if (Link.isLocation(location)) {
const name = location.aUnit.conformation.operator.name
serial = operatorNameSerialMap.get(name)
}
return serial === undefined ? DefaultColor : palette.color(serial)
}
} else {
color = () => DefaultColor
}
return {
factory: OperatorNameColorTheme,
granularity: 'instance',
color,
props,
description: Description,
legend
}
}
export const OperatorNameColorThemeProvider: ColorTheme.Provider<OperatorNameColorThemeParams> = {
label: 'Operator Name',
factory: OperatorNameColorTheme,
getParams: getOperatorNameColorThemeParams,
defaultValues: PD.getDefaultValues(OperatorNameColorThemeParams),
isApplicable: (ctx: ThemeDataContext) => !!ctx.structure
}
\ No newline at end of file
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment