/** * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose */ import { Unit, StructureProperties, StructureElement, Link } from 'mol-model/structure'; import { ColorScale, Color } from 'mol-util/color'; import { Location } from 'mol-model/location'; import { ColorTheme, LocationColor } from '../color'; import { ParamDefinition as PD } from 'mol-util/param-definition' import { ThemeDataContext } from 'mol-theme/theme'; import { ColorListOptions, ColorListName } from 'mol-util/color/scale'; import { Column } from 'mol-data/db'; import { Entities } from 'mol-model/structure/model/properties/common'; const DefaultColor = Color(0xCCCCCC) const Description = 'Gives every polymer chain a color based on its `asym_id` value.' export const PolymerIdColorThemeParams = { list: PD.ColorScale('RedYellowBlue', ColorListOptions), } export type PolymerIdColorThemeParams = typeof PolymerIdColorThemeParams export function getPolymerIdColorThemeParams(ctx: ThemeDataContext) { return PolymerIdColorThemeParams // TODO return copy } function getAsymId(unit: Unit): StructureElement.Property { switch (unit.kind) { case Unit.Kind.Atomic: return StructureProperties.chain.label_asym_id case Unit.Kind.Spheres: case Unit.Kind.Gaussians: return StructureProperties.coarse.asym_id } } function addPolymerAsymIds(map: Map, asymId: Column, entityId: Column, entities: Entities) { let j = map.size for (let o = 0, ol = asymId.rowCount; o < ol; ++o) { const e = entityId.value(o) const eI = entities.getEntityIndex(e) if (entities.data.type.value(eI) === 'polymer') { const k = asymId.value(o) if (!map.has(k)) { map.set(k, j) j += 1 } } } } export function PolymerIdColorTheme(ctx: ThemeDataContext, props: PD.Values): ColorTheme { let color: LocationColor const scale = ColorScale.create({ listOrName: props.list, minLabel: 'Start', maxLabel: 'End' }) if (ctx.structure) { const l = StructureElement.create() const { models } = ctx.structure const polymerAsymIdSerialMap = new Map() for (let i = 0, il = models.length; i { if (StructureElement.isLocation(location)) { const asym_id = getAsymId(location.unit) return scaleColor(polymerAsymIdSerialMap.get(asym_id(location)) || 0) } else if (Link.isLocation(location)) { const asym_id = getAsymId(location.aUnit) l.unit = location.aUnit l.element = location.aUnit.elements[location.aIndex] return scaleColor(polymerAsymIdSerialMap.get(asym_id(l)) || 0) } return DefaultColor } } else { color = () => DefaultColor } return { factory: PolymerIdColorTheme, granularity: 'group', color, props, description: Description, legend: scale ? scale.legend : undefined } } export const PolymerIdColorThemeProvider: ColorTheme.Provider = { label: 'Polymer Id', factory: PolymerIdColorTheme, getParams: getPolymerIdColorThemeParams, defaultValues: PD.getDefaultValues(PolymerIdColorThemeParams), isApplicable: (ctx: ThemeDataContext) => !!ctx.structure }