diff --git a/CHANGELOG.md b/CHANGELOG.md index e3f7fec9ffc516263b35a79b1225a725b8557a94..233f9a06d5fe730231585a5faaebaf982a405084 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ Note that since we don't clearly distinguish between a public and private interf - Add `.getCenter` and `.center` to `Camera` - Add support to dim unmarked groups - Add support for marker edge strength +- Factor out common code in `Dnatco` extension ## [v3.28.0] - 2022-12-20 diff --git a/src/extensions/dnatco/color.ts b/src/extensions/dnatco/color.ts new file mode 100644 index 0000000000000000000000000000000000000000..300bdc0a0b9836d9a21616a16dfd18a625bbadb0 --- /dev/null +++ b/src/extensions/dnatco/color.ts @@ -0,0 +1,219 @@ +/** + * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Michal Malý <michal.maly@ibt.cas.cz> + * @author Jiřà Černý <jiri.cerny@ibt.cas.cz> + */ + +import { Color, ColorMap } from '../../mol-util/color'; + +export const DefaultNtCClassColors = { + A: 0xFFC1C1, + B: 0xC8CFFF, + BII: 0x0059DA, + miB: 0x3BE8FB, + Z: 0x01F60E, + IC: 0xFA5CFB, + OPN: 0xE90000, + SYN: 0xFFFF01, + N: 0xF2F2F2, +}; +export const ErrorColor = Color(0xFFA10A); + +export const NtCColors = ColorMap({ + NANT_Upr: DefaultNtCClassColors.N, + NANT_Lwr: DefaultNtCClassColors.N, + AA00_Upr: DefaultNtCClassColors.A, + AA00_Lwr: DefaultNtCClassColors.A, + AA02_Upr: DefaultNtCClassColors.A, + AA02_Lwr: DefaultNtCClassColors.A, + AA03_Upr: DefaultNtCClassColors.A, + AA03_Lwr: DefaultNtCClassColors.A, + AA04_Upr: DefaultNtCClassColors.A, + AA04_Lwr: DefaultNtCClassColors.A, + AA08_Upr: DefaultNtCClassColors.A, + AA08_Lwr: DefaultNtCClassColors.A, + AA09_Upr: DefaultNtCClassColors.A, + AA09_Lwr: DefaultNtCClassColors.A, + AA01_Upr: DefaultNtCClassColors.A, + AA01_Lwr: DefaultNtCClassColors.A, + AA05_Upr: DefaultNtCClassColors.A, + AA05_Lwr: DefaultNtCClassColors.A, + AA06_Upr: DefaultNtCClassColors.A, + AA06_Lwr: DefaultNtCClassColors.A, + AA10_Upr: DefaultNtCClassColors.A, + AA10_Lwr: DefaultNtCClassColors.A, + AA11_Upr: DefaultNtCClassColors.A, + AA11_Lwr: DefaultNtCClassColors.A, + AA07_Upr: DefaultNtCClassColors.A, + AA07_Lwr: DefaultNtCClassColors.A, + AA12_Upr: DefaultNtCClassColors.A, + AA12_Lwr: DefaultNtCClassColors.A, + AA13_Upr: DefaultNtCClassColors.A, + AA13_Lwr: DefaultNtCClassColors.A, + AB01_Upr: DefaultNtCClassColors.A, + AB01_Lwr: DefaultNtCClassColors.B, + AB02_Upr: DefaultNtCClassColors.A, + AB02_Lwr: DefaultNtCClassColors.B, + AB03_Upr: DefaultNtCClassColors.A, + AB03_Lwr: DefaultNtCClassColors.B, + AB04_Upr: DefaultNtCClassColors.A, + AB04_Lwr: DefaultNtCClassColors.B, + AB05_Upr: DefaultNtCClassColors.A, + AB05_Lwr: DefaultNtCClassColors.B, + BA01_Upr: DefaultNtCClassColors.B, + BA01_Lwr: DefaultNtCClassColors.A, + BA05_Upr: DefaultNtCClassColors.B, + BA05_Lwr: DefaultNtCClassColors.A, + BA09_Upr: DefaultNtCClassColors.B, + BA09_Lwr: DefaultNtCClassColors.A, + BA08_Upr: DefaultNtCClassColors.BII, + BA08_Lwr: DefaultNtCClassColors.A, + BA10_Upr: DefaultNtCClassColors.B, + BA10_Lwr: DefaultNtCClassColors.A, + BA13_Upr: DefaultNtCClassColors.BII, + BA13_Lwr: DefaultNtCClassColors.A, + BA16_Upr: DefaultNtCClassColors.BII, + BA16_Lwr: DefaultNtCClassColors.A, + BA17_Upr: DefaultNtCClassColors.BII, + BA17_Lwr: DefaultNtCClassColors.A, + BB00_Upr: DefaultNtCClassColors.B, + BB00_Lwr: DefaultNtCClassColors.B, + BB01_Upr: DefaultNtCClassColors.B, + BB01_Lwr: DefaultNtCClassColors.B, + BB17_Upr: DefaultNtCClassColors.B, + BB17_Lwr: DefaultNtCClassColors.B, + BB02_Upr: DefaultNtCClassColors.B, + BB02_Lwr: DefaultNtCClassColors.B, + BB03_Upr: DefaultNtCClassColors.B, + BB03_Lwr: DefaultNtCClassColors.B, + BB11_Upr: DefaultNtCClassColors.B, + BB11_Lwr: DefaultNtCClassColors.B, + BB16_Upr: DefaultNtCClassColors.B, + BB16_Lwr: DefaultNtCClassColors.B, + BB04_Upr: DefaultNtCClassColors.B, + BB04_Lwr: DefaultNtCClassColors.BII, + BB05_Upr: DefaultNtCClassColors.B, + BB05_Lwr: DefaultNtCClassColors.BII, + BB07_Upr: DefaultNtCClassColors.BII, + BB07_Lwr: DefaultNtCClassColors.BII, + BB08_Upr: DefaultNtCClassColors.BII, + BB08_Lwr: DefaultNtCClassColors.BII, + BB10_Upr: DefaultNtCClassColors.miB, + BB10_Lwr: DefaultNtCClassColors.miB, + BB12_Upr: DefaultNtCClassColors.miB, + BB12_Lwr: DefaultNtCClassColors.miB, + BB13_Upr: DefaultNtCClassColors.miB, + BB13_Lwr: DefaultNtCClassColors.miB, + BB14_Upr: DefaultNtCClassColors.miB, + BB14_Lwr: DefaultNtCClassColors.miB, + BB15_Upr: DefaultNtCClassColors.miB, + BB15_Lwr: DefaultNtCClassColors.miB, + BB20_Upr: DefaultNtCClassColors.miB, + BB20_Lwr: DefaultNtCClassColors.miB, + IC01_Upr: DefaultNtCClassColors.IC, + IC01_Lwr: DefaultNtCClassColors.IC, + IC02_Upr: DefaultNtCClassColors.IC, + IC02_Lwr: DefaultNtCClassColors.IC, + IC03_Upr: DefaultNtCClassColors.IC, + IC03_Lwr: DefaultNtCClassColors.IC, + IC04_Upr: DefaultNtCClassColors.IC, + IC04_Lwr: DefaultNtCClassColors.IC, + IC05_Upr: DefaultNtCClassColors.IC, + IC05_Lwr: DefaultNtCClassColors.IC, + IC06_Upr: DefaultNtCClassColors.IC, + IC06_Lwr: DefaultNtCClassColors.IC, + IC07_Upr: DefaultNtCClassColors.IC, + IC07_Lwr: DefaultNtCClassColors.IC, + OP01_Upr: DefaultNtCClassColors.OPN, + OP01_Lwr: DefaultNtCClassColors.OPN, + OP02_Upr: DefaultNtCClassColors.OPN, + OP02_Lwr: DefaultNtCClassColors.OPN, + OP03_Upr: DefaultNtCClassColors.OPN, + OP03_Lwr: DefaultNtCClassColors.OPN, + OP04_Upr: DefaultNtCClassColors.OPN, + OP04_Lwr: DefaultNtCClassColors.OPN, + OP05_Upr: DefaultNtCClassColors.OPN, + OP05_Lwr: DefaultNtCClassColors.OPN, + OP06_Upr: DefaultNtCClassColors.OPN, + OP06_Lwr: DefaultNtCClassColors.OPN, + OP07_Upr: DefaultNtCClassColors.OPN, + OP07_Lwr: DefaultNtCClassColors.OPN, + OP08_Upr: DefaultNtCClassColors.OPN, + OP08_Lwr: DefaultNtCClassColors.OPN, + OP09_Upr: DefaultNtCClassColors.OPN, + OP09_Lwr: DefaultNtCClassColors.OPN, + OP10_Upr: DefaultNtCClassColors.OPN, + OP10_Lwr: DefaultNtCClassColors.OPN, + OP11_Upr: DefaultNtCClassColors.OPN, + OP11_Lwr: DefaultNtCClassColors.OPN, + OP12_Upr: DefaultNtCClassColors.OPN, + OP12_Lwr: DefaultNtCClassColors.OPN, + OP13_Upr: DefaultNtCClassColors.OPN, + OP13_Lwr: DefaultNtCClassColors.OPN, + OP14_Upr: DefaultNtCClassColors.OPN, + OP14_Lwr: DefaultNtCClassColors.OPN, + OP15_Upr: DefaultNtCClassColors.OPN, + OP15_Lwr: DefaultNtCClassColors.OPN, + OP16_Upr: DefaultNtCClassColors.OPN, + OP16_Lwr: DefaultNtCClassColors.OPN, + OP17_Upr: DefaultNtCClassColors.OPN, + OP17_Lwr: DefaultNtCClassColors.OPN, + OP18_Upr: DefaultNtCClassColors.OPN, + OP18_Lwr: DefaultNtCClassColors.OPN, + OP19_Upr: DefaultNtCClassColors.OPN, + OP19_Lwr: DefaultNtCClassColors.OPN, + OP20_Upr: DefaultNtCClassColors.OPN, + OP20_Lwr: DefaultNtCClassColors.OPN, + OP21_Upr: DefaultNtCClassColors.OPN, + OP21_Lwr: DefaultNtCClassColors.OPN, + OP22_Upr: DefaultNtCClassColors.OPN, + OP22_Lwr: DefaultNtCClassColors.OPN, + OP23_Upr: DefaultNtCClassColors.OPN, + OP23_Lwr: DefaultNtCClassColors.OPN, + OP24_Upr: DefaultNtCClassColors.OPN, + OP24_Lwr: DefaultNtCClassColors.OPN, + OP25_Upr: DefaultNtCClassColors.OPN, + OP25_Lwr: DefaultNtCClassColors.OPN, + OP26_Upr: DefaultNtCClassColors.OPN, + OP26_Lwr: DefaultNtCClassColors.OPN, + OP27_Upr: DefaultNtCClassColors.OPN, + OP27_Lwr: DefaultNtCClassColors.OPN, + OP28_Upr: DefaultNtCClassColors.OPN, + OP28_Lwr: DefaultNtCClassColors.OPN, + OP29_Upr: DefaultNtCClassColors.OPN, + OP29_Lwr: DefaultNtCClassColors.OPN, + OP30_Upr: DefaultNtCClassColors.OPN, + OP30_Lwr: DefaultNtCClassColors.OPN, + OP31_Upr: DefaultNtCClassColors.OPN, + OP31_Lwr: DefaultNtCClassColors.OPN, + OPS1_Upr: DefaultNtCClassColors.OPN, + OPS1_Lwr: DefaultNtCClassColors.OPN, + OP1S_Upr: DefaultNtCClassColors.OPN, + OP1S_Lwr: DefaultNtCClassColors.SYN, + AAS1_Upr: DefaultNtCClassColors.SYN, + AAS1_Lwr: DefaultNtCClassColors.A, + AB1S_Upr: DefaultNtCClassColors.A, + AB1S_Lwr: DefaultNtCClassColors.SYN, + AB2S_Upr: DefaultNtCClassColors.A, + AB2S_Lwr: DefaultNtCClassColors.SYN, + BB1S_Upr: DefaultNtCClassColors.B, + BB1S_Lwr: DefaultNtCClassColors.SYN, + BB2S_Upr: DefaultNtCClassColors.B, + BB2S_Lwr: DefaultNtCClassColors.SYN, + BBS1_Upr: DefaultNtCClassColors.SYN, + BBS1_Lwr: DefaultNtCClassColors.B, + ZZ01_Upr: DefaultNtCClassColors.Z, + ZZ01_Lwr: DefaultNtCClassColors.Z, + ZZ02_Upr: DefaultNtCClassColors.Z, + ZZ02_Lwr: DefaultNtCClassColors.Z, + ZZ1S_Upr: DefaultNtCClassColors.Z, + ZZ1S_Lwr: DefaultNtCClassColors.SYN, + ZZ2S_Upr: DefaultNtCClassColors.Z, + ZZ2S_Lwr: DefaultNtCClassColors.SYN, + ZZS1_Upr: DefaultNtCClassColors.SYN, + ZZS1_Lwr: DefaultNtCClassColors.Z, + ZZS2_Upr: DefaultNtCClassColors.SYN, + ZZS2_Lwr: DefaultNtCClassColors.Z, +}); + diff --git a/src/extensions/dnatco/confal-pyramids/behavior.ts b/src/extensions/dnatco/confal-pyramids/behavior.ts index 7c34704ae344e745aa3ad5b0e0fc948d199dd588..b793ee7b61a670c0b3f03bacc25cc89f824d2e49 100644 --- a/src/extensions/dnatco/confal-pyramids/behavior.ts +++ b/src/extensions/dnatco/confal-pyramids/behavior.ts @@ -6,9 +6,10 @@ */ import { ConfalPyramidsColorThemeProvider } from './color'; -import { ConfalPyramids, ConfalPyramidsProvider } from './property'; +import { ConfalPyramidsProvider } from './property'; import { ConfalPyramidsRepresentationProvider } from './representation'; -import { ConfalPyramidsTypes } from './types'; +import { Dnatco } from '../property'; +import { DnatcoTypes } from '../types'; import { PluginBehavior } from '../../../mol-plugin/behavior/behavior'; import { StructureRepresentationPresetProvider, PresetStructureRepresentations } from '../../../mol-plugin-state/builder/structure/representation-preset'; import { StateObjectRef } from '../../../mol-state'; @@ -22,7 +23,7 @@ export const DnatcoConfalPyramidsPreset = StructureRepresentationPresetProvider( description: 'Schematic depiction of conformer class and confal value.', }, isApplicable(a) { - return a.data.models.length >= 1 && a.data.models.some(m => ConfalPyramids.isApplicable(m)); + return a.data.models.length >= 1 && a.data.models.some(m => Dnatco.isApplicable(m)); }, params: () => StructureRepresentationPresetProvider.CommonParams, async apply(ref, params, plugin) { @@ -90,8 +91,8 @@ export const DnatcoConfalPyramids = PluginBehavior.create<{ autoAttach: boolean, }) }); -export function confalPyramidLabel(halfPyramid: ConfalPyramidsTypes.HalfPyramid) { - const { step } = halfPyramid; +export function confalPyramidLabel(halfStep: DnatcoTypes.HalfStep) { + const { step } = halfStep; return ` <b>${step.auth_asym_id_1}</b> | <b>${step.label_comp_id_1} ${step.auth_seq_id_1}${step.PDB_ins_code_1}${step.label_alt_id_1.length > 0 ? ` (alt ${step.label_alt_id_1})` : ''} diff --git a/src/extensions/dnatco/confal-pyramids/color.ts b/src/extensions/dnatco/confal-pyramids/color.ts index 1cf4ad87052d33ce98c58c19fe73c39bc8f08726..5b351545b7edc0c5459cabff38ec482c0c232fc8 100644 --- a/src/extensions/dnatco/confal-pyramids/color.ts +++ b/src/extensions/dnatco/confal-pyramids/color.ts @@ -5,8 +5,10 @@ * @author Jiřà Černý <jiri.cerny@ibt.cas.cz> */ -import { ConfalPyramids, ConfalPyramidsProvider } from './property'; +import { ErrorColor, NtCColors } from '../color'; +import { ConfalPyramidsProvider } from './property'; import { ConfalPyramidsTypes as CPT } from './types'; +import { Dnatco } from '../property'; import { Location } from '../../../mol-model/location'; import { CustomProperty } from '../../../mol-model-props/common/custom-property'; import { ColorTheme } from '../../../mol-theme/color'; @@ -19,215 +21,7 @@ import { ObjectKeys } from '../../../mol-util/type-helpers'; const Description = 'Assigns colors to confal pyramids'; -const DefaultClassColors = { - A: 0xFFC1C1, - B: 0xC8CFFF, - BII: 0x0059DA, - miB: 0x3BE8FB, - Z: 0x01F60E, - IC: 0xFA5CFB, - OPN: 0xE90000, - SYN: 0xFFFF01, - N: 0xF2F2F2, -}; -const ErrorColor = Color(0xFFA10A); - -const PyramidsColors = ColorMap({ - NANT_Upr: DefaultClassColors.N, - NANT_Lwr: DefaultClassColors.N, - AA00_Upr: DefaultClassColors.A, - AA00_Lwr: DefaultClassColors.A, - AA02_Upr: DefaultClassColors.A, - AA02_Lwr: DefaultClassColors.A, - AA03_Upr: DefaultClassColors.A, - AA03_Lwr: DefaultClassColors.A, - AA04_Upr: DefaultClassColors.A, - AA04_Lwr: DefaultClassColors.A, - AA08_Upr: DefaultClassColors.A, - AA08_Lwr: DefaultClassColors.A, - AA09_Upr: DefaultClassColors.A, - AA09_Lwr: DefaultClassColors.A, - AA01_Upr: DefaultClassColors.A, - AA01_Lwr: DefaultClassColors.A, - AA05_Upr: DefaultClassColors.A, - AA05_Lwr: DefaultClassColors.A, - AA06_Upr: DefaultClassColors.A, - AA06_Lwr: DefaultClassColors.A, - AA10_Upr: DefaultClassColors.A, - AA10_Lwr: DefaultClassColors.A, - AA11_Upr: DefaultClassColors.A, - AA11_Lwr: DefaultClassColors.A, - AA07_Upr: DefaultClassColors.A, - AA07_Lwr: DefaultClassColors.A, - AA12_Upr: DefaultClassColors.A, - AA12_Lwr: DefaultClassColors.A, - AA13_Upr: DefaultClassColors.A, - AA13_Lwr: DefaultClassColors.A, - AB01_Upr: DefaultClassColors.A, - AB01_Lwr: DefaultClassColors.B, - AB02_Upr: DefaultClassColors.A, - AB02_Lwr: DefaultClassColors.B, - AB03_Upr: DefaultClassColors.A, - AB03_Lwr: DefaultClassColors.B, - AB04_Upr: DefaultClassColors.A, - AB04_Lwr: DefaultClassColors.B, - AB05_Upr: DefaultClassColors.A, - AB05_Lwr: DefaultClassColors.B, - BA01_Upr: DefaultClassColors.B, - BA01_Lwr: DefaultClassColors.A, - BA05_Upr: DefaultClassColors.B, - BA05_Lwr: DefaultClassColors.A, - BA09_Upr: DefaultClassColors.B, - BA09_Lwr: DefaultClassColors.A, - BA08_Upr: DefaultClassColors.BII, - BA08_Lwr: DefaultClassColors.A, - BA10_Upr: DefaultClassColors.B, - BA10_Lwr: DefaultClassColors.A, - BA13_Upr: DefaultClassColors.BII, - BA13_Lwr: DefaultClassColors.A, - BA16_Upr: DefaultClassColors.BII, - BA16_Lwr: DefaultClassColors.A, - BA17_Upr: DefaultClassColors.BII, - BA17_Lwr: DefaultClassColors.A, - BB00_Upr: DefaultClassColors.B, - BB00_Lwr: DefaultClassColors.B, - BB01_Upr: DefaultClassColors.B, - BB01_Lwr: DefaultClassColors.B, - BB17_Upr: DefaultClassColors.B, - BB17_Lwr: DefaultClassColors.B, - BB02_Upr: DefaultClassColors.B, - BB02_Lwr: DefaultClassColors.B, - BB03_Upr: DefaultClassColors.B, - BB03_Lwr: DefaultClassColors.B, - BB11_Upr: DefaultClassColors.B, - BB11_Lwr: DefaultClassColors.B, - BB16_Upr: DefaultClassColors.B, - BB16_Lwr: DefaultClassColors.B, - BB04_Upr: DefaultClassColors.B, - BB04_Lwr: DefaultClassColors.BII, - BB05_Upr: DefaultClassColors.B, - BB05_Lwr: DefaultClassColors.BII, - BB07_Upr: DefaultClassColors.BII, - BB07_Lwr: DefaultClassColors.BII, - BB08_Upr: DefaultClassColors.BII, - BB08_Lwr: DefaultClassColors.BII, - BB10_Upr: DefaultClassColors.miB, - BB10_Lwr: DefaultClassColors.miB, - BB12_Upr: DefaultClassColors.miB, - BB12_Lwr: DefaultClassColors.miB, - BB13_Upr: DefaultClassColors.miB, - BB13_Lwr: DefaultClassColors.miB, - BB14_Upr: DefaultClassColors.miB, - BB14_Lwr: DefaultClassColors.miB, - BB15_Upr: DefaultClassColors.miB, - BB15_Lwr: DefaultClassColors.miB, - BB20_Upr: DefaultClassColors.miB, - BB20_Lwr: DefaultClassColors.miB, - IC01_Upr: DefaultClassColors.IC, - IC01_Lwr: DefaultClassColors.IC, - IC02_Upr: DefaultClassColors.IC, - IC02_Lwr: DefaultClassColors.IC, - IC03_Upr: DefaultClassColors.IC, - IC03_Lwr: DefaultClassColors.IC, - IC04_Upr: DefaultClassColors.IC, - IC04_Lwr: DefaultClassColors.IC, - IC05_Upr: DefaultClassColors.IC, - IC05_Lwr: DefaultClassColors.IC, - IC06_Upr: DefaultClassColors.IC, - IC06_Lwr: DefaultClassColors.IC, - IC07_Upr: DefaultClassColors.IC, - IC07_Lwr: DefaultClassColors.IC, - OP01_Upr: DefaultClassColors.OPN, - OP01_Lwr: DefaultClassColors.OPN, - OP02_Upr: DefaultClassColors.OPN, - OP02_Lwr: DefaultClassColors.OPN, - OP03_Upr: DefaultClassColors.OPN, - OP03_Lwr: DefaultClassColors.OPN, - OP04_Upr: DefaultClassColors.OPN, - OP04_Lwr: DefaultClassColors.OPN, - OP05_Upr: DefaultClassColors.OPN, - OP05_Lwr: DefaultClassColors.OPN, - OP06_Upr: DefaultClassColors.OPN, - OP06_Lwr: DefaultClassColors.OPN, - OP07_Upr: DefaultClassColors.OPN, - OP07_Lwr: DefaultClassColors.OPN, - OP08_Upr: DefaultClassColors.OPN, - OP08_Lwr: DefaultClassColors.OPN, - OP09_Upr: DefaultClassColors.OPN, - OP09_Lwr: DefaultClassColors.OPN, - OP10_Upr: DefaultClassColors.OPN, - OP10_Lwr: DefaultClassColors.OPN, - OP11_Upr: DefaultClassColors.OPN, - OP11_Lwr: DefaultClassColors.OPN, - OP12_Upr: DefaultClassColors.OPN, - OP12_Lwr: DefaultClassColors.OPN, - OP13_Upr: DefaultClassColors.OPN, - OP13_Lwr: DefaultClassColors.OPN, - OP14_Upr: DefaultClassColors.OPN, - OP14_Lwr: DefaultClassColors.OPN, - OP15_Upr: DefaultClassColors.OPN, - OP15_Lwr: DefaultClassColors.OPN, - OP16_Upr: DefaultClassColors.OPN, - OP16_Lwr: DefaultClassColors.OPN, - OP17_Upr: DefaultClassColors.OPN, - OP17_Lwr: DefaultClassColors.OPN, - OP18_Upr: DefaultClassColors.OPN, - OP18_Lwr: DefaultClassColors.OPN, - OP19_Upr: DefaultClassColors.OPN, - OP19_Lwr: DefaultClassColors.OPN, - OP20_Upr: DefaultClassColors.OPN, - OP20_Lwr: DefaultClassColors.OPN, - OP21_Upr: DefaultClassColors.OPN, - OP21_Lwr: DefaultClassColors.OPN, - OP22_Upr: DefaultClassColors.OPN, - OP22_Lwr: DefaultClassColors.OPN, - OP23_Upr: DefaultClassColors.OPN, - OP23_Lwr: DefaultClassColors.OPN, - OP24_Upr: DefaultClassColors.OPN, - OP24_Lwr: DefaultClassColors.OPN, - OP25_Upr: DefaultClassColors.OPN, - OP25_Lwr: DefaultClassColors.OPN, - OP26_Upr: DefaultClassColors.OPN, - OP26_Lwr: DefaultClassColors.OPN, - OP27_Upr: DefaultClassColors.OPN, - OP27_Lwr: DefaultClassColors.OPN, - OP28_Upr: DefaultClassColors.OPN, - OP28_Lwr: DefaultClassColors.OPN, - OP29_Upr: DefaultClassColors.OPN, - OP29_Lwr: DefaultClassColors.OPN, - OP30_Upr: DefaultClassColors.OPN, - OP30_Lwr: DefaultClassColors.OPN, - OP31_Upr: DefaultClassColors.OPN, - OP31_Lwr: DefaultClassColors.OPN, - OPS1_Upr: DefaultClassColors.OPN, - OPS1_Lwr: DefaultClassColors.OPN, - OP1S_Upr: DefaultClassColors.OPN, - OP1S_Lwr: DefaultClassColors.SYN, - AAS1_Upr: DefaultClassColors.SYN, - AAS1_Lwr: DefaultClassColors.A, - AB1S_Upr: DefaultClassColors.A, - AB1S_Lwr: DefaultClassColors.SYN, - AB2S_Upr: DefaultClassColors.A, - AB2S_Lwr: DefaultClassColors.SYN, - BB1S_Upr: DefaultClassColors.B, - BB1S_Lwr: DefaultClassColors.SYN, - BB2S_Upr: DefaultClassColors.B, - BB2S_Lwr: DefaultClassColors.SYN, - BBS1_Upr: DefaultClassColors.SYN, - BBS1_Lwr: DefaultClassColors.B, - ZZ01_Upr: DefaultClassColors.Z, - ZZ01_Lwr: DefaultClassColors.Z, - ZZ02_Upr: DefaultClassColors.Z, - ZZ02_Lwr: DefaultClassColors.Z, - ZZ1S_Upr: DefaultClassColors.Z, - ZZ1S_Lwr: DefaultClassColors.SYN, - ZZ2S_Upr: DefaultClassColors.Z, - ZZ2S_Lwr: DefaultClassColors.SYN, - ZZS1_Upr: DefaultClassColors.SYN, - ZZS1_Lwr: DefaultClassColors.Z, - ZZS2_Upr: DefaultClassColors.SYN, - ZZS2_Lwr: DefaultClassColors.Z, -}); +const PyramidsColors = ColorMap({ ...NtCColors }); type PyramidsColors = typeof PyramidsColors; export const ConfalPyramidsColorThemeParams = { @@ -272,7 +66,7 @@ export const ConfalPyramidsColorThemeProvider: ColorTheme.Provider<ConfalPyramid factory: ConfalPyramidsColorTheme, getParams: getConfalPyramidsColorThemeParams, defaultValues: PD.getDefaultValues(ConfalPyramidsColorThemeParams), - isApplicable: (ctx: ThemeDataContext) => !!ctx.structure && ctx.structure.models.some(m => ConfalPyramids.isApplicable(m)), + isApplicable: (ctx: ThemeDataContext) => !!ctx.structure && ctx.structure.models.some(m => Dnatco.isApplicable(m)), ensureCustomProperties: { attach: (ctx: CustomProperty.Context, data: ThemeDataContext) => data.structure ? ConfalPyramidsProvider.attach(ctx, data.structure.models[0], void 0, true) : Promise.resolve(), detach: (data) => data.structure && ConfalPyramidsProvider.ref(data.structure.models[0], false) diff --git a/src/extensions/dnatco/confal-pyramids/property.ts b/src/extensions/dnatco/confal-pyramids/property.ts index 5ca7bada8ce41ae7c0ceb7c51291a891ce06ab8d..05539fb7d0206de6b60082a9fab6988e32892c3a 100644 --- a/src/extensions/dnatco/confal-pyramids/property.ts +++ b/src/extensions/dnatco/confal-pyramids/property.ts @@ -5,90 +5,18 @@ * @author Jiřà Černý <jiri.cerny@ibt.cas.cz> */ -import { ConfalPyramidsTypes as CPT } from './types'; -import { Column, Table } from '../../../mol-data/db'; -import { toTable } from '../../../mol-io/reader/cif/schema'; +import { Dnatco, DnatcoParams, DnatcoSteps } from '../property'; import { CustomPropertyDescriptor } from '../../../mol-model/custom-property'; import { Model } from '../../../mol-model/structure'; import { CustomProperty } from '../../../mol-model-props/common/custom-property'; import { CustomModelProperty } from '../../../mol-model-props/common/custom-model-property'; -import { PropertyWrapper } from '../../../mol-model-props/common/wrapper'; import { ParamDefinition as PD } from '../../../mol-util/param-definition'; -import { MmcifFormat } from '../../../mol-model-formats/structure/mmcif'; -export type ConfalPyramids = PropertyWrapper<CPT.Steps | undefined>; - -export namespace ConfalPyramids { - export const Schema = { - ndb_struct_ntc_step: { - id: Column.Schema.int, - name: Column.Schema.str, - PDB_model_number: Column.Schema.int, - label_entity_id_1: Column.Schema.int, - label_asym_id_1: Column.Schema.str, - label_seq_id_1: Column.Schema.int, - label_comp_id_1: Column.Schema.str, - label_alt_id_1: Column.Schema.str, - label_entity_id_2: Column.Schema.int, - label_asym_id_2: Column.Schema.str, - label_seq_id_2: Column.Schema.int, - label_comp_id_2: Column.Schema.str, - label_alt_id_2: Column.Schema.str, - auth_asym_id_1: Column.Schema.str, - auth_seq_id_1: Column.Schema.int, - auth_asym_id_2: Column.Schema.str, - auth_seq_id_2: Column.Schema.int, - PDB_ins_code_1: Column.Schema.str, - PDB_ins_code_2: Column.Schema.str, - }, - ndb_struct_ntc_step_summary: { - step_id: Column.Schema.int, - assigned_CANA: Column.Schema.str, - assigned_NtC: Column.Schema.str, - confal_score: Column.Schema.int, - euclidean_distance_NtC_ideal: Column.Schema.float, - cartesian_rmsd_closest_NtC_representative: Column.Schema.float, - closest_CANA: Column.Schema.str, - closest_NtC: Column.Schema.str, - closest_step_golden: Column.Schema.str - } - }; - export type Schema = typeof Schema; - - export async function fromCif(ctx: CustomProperty.Context, model: Model, props: ConfalPyramidsProps): Promise<CustomProperty.Data<ConfalPyramids>> { - const info = PropertyWrapper.createInfo(); - const data = getCifData(model); - if (data === undefined) return { value: { info, data: undefined } }; - - const fromCif = createPyramidsFromCif(model, data.steps, data.stepsSummary); - return { value: { info, data: fromCif } }; - } - - function getCifData(model: Model) { - if (!MmcifFormat.is(model.sourceData)) throw new Error('Data format must be mmCIF'); - if (!hasNdbStructNtcCategories(model)) return undefined; - return { - steps: toTable(Schema.ndb_struct_ntc_step, model.sourceData.data.frame.categories.ndb_struct_ntc_step), - stepsSummary: toTable(Schema.ndb_struct_ntc_step_summary, model.sourceData.data.frame.categories.ndb_struct_ntc_step_summary) - }; - } - - function hasNdbStructNtcCategories(model: Model): boolean { - if (!MmcifFormat.is(model.sourceData)) return false; - const names = (model.sourceData).data.frame.categoryNames; - return names.includes('ndb_struct_ntc_step') && names.includes('ndb_struct_ntc_step_summary'); - } - - export function isApplicable(model?: Model): boolean { - return !!model && hasNdbStructNtcCategories(model); - } -} - -export const ConfalPyramidsParams = {}; +export const ConfalPyramidsParams = { ...DnatcoParams }; export type ConfalPyramidsParams = typeof ConfalPyramidsParams; export type ConfalPyramidsProps = PD.Values<ConfalPyramidsParams>; -export const ConfalPyramidsProvider: CustomModelProperty.Provider<ConfalPyramidsParams, ConfalPyramids> = CustomModelProperty.createProvider({ +export const ConfalPyramidsProvider: CustomModelProperty.Provider<ConfalPyramidsParams, DnatcoSteps> = CustomModelProperty.createProvider({ label: 'Confal Pyramids', descriptor: CustomPropertyDescriptor({ name: 'confal_pyramids', @@ -96,94 +24,9 @@ export const ConfalPyramidsProvider: CustomModelProperty.Provider<ConfalPyramids type: 'static', defaultParams: ConfalPyramidsParams, getParams: (data: Model) => ConfalPyramidsParams, - isApplicable: (data: Model) => ConfalPyramids.isApplicable(data), + isApplicable: (data: Model) => Dnatco.isApplicable(data), obtain: async (ctx: CustomProperty.Context, data: Model, props: Partial<ConfalPyramidsProps>) => { const p = { ...PD.getDefaultValues(ConfalPyramidsParams), ...props }; - return ConfalPyramids.fromCif(ctx, data, p); + return Dnatco.fromCif(ctx, data, p); } }); - -type StepsSummaryTable = Table<typeof ConfalPyramids.Schema.ndb_struct_ntc_step_summary>; - -function createPyramidsFromCif( - model: Model, - cifSteps: Table<typeof ConfalPyramids.Schema.ndb_struct_ntc_step>, - stepsSummary: StepsSummaryTable -): CPT.Steps { - const steps = new Array<CPT.Step>(); - const mapping = new Array<CPT.MappedChains>(); - - const { - id, PDB_model_number, name, - auth_asym_id_1, auth_seq_id_1, label_comp_id_1, label_alt_id_1, PDB_ins_code_1, - auth_asym_id_2, auth_seq_id_2, label_comp_id_2, label_alt_id_2, PDB_ins_code_2, - _rowCount - } = cifSteps; - - if (_rowCount !== stepsSummary._rowCount) throw new Error('Inconsistent mmCIF data'); - - for (let i = 0; i < _rowCount; i++) { - const { - NtC, - confal_score, - rmsd - } = getSummaryData(id.value(i), i, stepsSummary); - const modelNum = PDB_model_number.value(i); - const chainId = auth_asym_id_1.value(i); - const seqId = auth_seq_id_1.value(i); - const modelIdx = modelNum - 1; - - if (mapping.length <= modelIdx || !mapping[modelIdx]) - mapping[modelIdx] = new Map<string, CPT.MappedResidues>(); - - const step = { - PDB_model_number: modelNum, - name: name.value(i), - auth_asym_id_1: chainId, - auth_seq_id_1: seqId, - label_comp_id_1: label_comp_id_1.value(i), - label_alt_id_1: label_alt_id_1.value(i), - PDB_ins_code_1: PDB_ins_code_1.value(i), - auth_asym_id_2: auth_asym_id_2.value(i), - auth_seq_id_2: auth_seq_id_2.value(i), - label_comp_id_2: label_comp_id_2.value(i), - label_alt_id_2: label_alt_id_2.value(i), - PDB_ins_code_2: PDB_ins_code_2.value(i), - confal_score, - NtC, - rmsd, - }; - - steps.push(step); - - const mappedChains = mapping[modelIdx]; - const residuesOnChain = mappedChains.get(chainId) ?? new Map<number, number[]>(); - const stepsForResidue = residuesOnChain.get(seqId) ?? []; - stepsForResidue.push(steps.length - 1); - - residuesOnChain.set(seqId, stepsForResidue); - mappedChains.set(chainId, residuesOnChain); - mapping[modelIdx] = mappedChains; - } - - return { steps, mapping }; -} - -function getSummaryData(id: number, i: number, stepsSummary: StepsSummaryTable) { - const { - step_id, - confal_score, - assigned_NtC, - cartesian_rmsd_closest_NtC_representative, - } = stepsSummary; - - // Assume that step_ids in ntc_step_summary are in the same order as steps in ntc_step - for (let j = i; j < stepsSummary._rowCount; j++) { - if (id === step_id.value(j)) return { NtC: assigned_NtC.value(j), confal_score: confal_score.value(j), rmsd: cartesian_rmsd_closest_NtC_representative.value(j) }; - } - // Safety net for cases where the previous assumption is not met - for (let j = 0; j < i; j++) { - if (id === step_id.value(j)) return { NtC: assigned_NtC.value(j), confal_score: confal_score.value(j), rmsd: cartesian_rmsd_closest_NtC_representative.value(j) }; - } - throw new Error('Inconsistent mmCIF data'); -} diff --git a/src/extensions/dnatco/confal-pyramids/representation.ts b/src/extensions/dnatco/confal-pyramids/representation.ts index 1c7d4f95b1e05aaa06298becd8a4d7f89ecba911..60a77075dd4305ff1a309802f74e02f9f27680f5 100644 --- a/src/extensions/dnatco/confal-pyramids/representation.ts +++ b/src/extensions/dnatco/confal-pyramids/representation.ts @@ -5,9 +5,10 @@ * @author Jiřà Černý <jiri.cerny@ibt.cas.cz> */ -import { ConfalPyramids, ConfalPyramidsProvider } from './property'; +import { ConfalPyramidsProvider } from './property'; import { ConfalPyramidsIterator } from './util'; import { ConfalPyramidsTypes as CPT } from './types'; +import { Dnatco } from '../property'; import { Interval } from '../../../mol-data/int'; import { Mesh } from '../../../mol-geo/geometry/mesh/mesh'; import { MeshBuilder } from '../../../mol-geo/geometry/mesh/mesh-builder'; @@ -197,7 +198,7 @@ export const ConfalPyramidsRepresentationProvider = StructureRepresentationProvi defaultValues: PD.getDefaultValues(ConfalPyramidsParams), defaultColorTheme: { name: 'confal-pyramids' }, defaultSizeTheme: { name: 'uniform' }, - isApplicable: (structure: Structure) => structure.models.some(m => ConfalPyramids.isApplicable(m)), + isApplicable: (structure: Structure) => structure.models.some(m => Dnatco.isApplicable(m)), ensureCustomProperties: { attach: (ctx: CustomProperty.Context, structure: Structure) => ConfalPyramidsProvider.attach(ctx, structure.model, void 0, true), detach: (data) => ConfalPyramidsProvider.ref(data.model, false), diff --git a/src/extensions/dnatco/confal-pyramids/types.ts b/src/extensions/dnatco/confal-pyramids/types.ts index f2b898822333d901e9d99789e1a93fd1ef4f4cf2..89363cc140b0d7b0756bad5c21796139a9a785cd 100644 --- a/src/extensions/dnatco/confal-pyramids/types.ts +++ b/src/extensions/dnatco/confal-pyramids/types.ts @@ -5,61 +5,29 @@ * @author Jiřà Černý <jiri.cerny@ibt.cas.cz> */ +import { DnatcoTypes } from '../types'; import { DataLocation } from '../../../mol-model/location'; import { DataLoci } from '../../../mol-model/loci'; import { confalPyramidLabel } from './behavior'; export namespace ConfalPyramidsTypes { - export const DataTag = 'dnatco-confal-half-pyramid'; + export interface Location extends DataLocation<DnatcoTypes.HalfStep, {}> {} - export type Step = { - PDB_model_number: number, - name: string, - auth_asym_id_1: string, - auth_seq_id_1: number, - label_comp_id_1: string, - label_alt_id_1: string, - PDB_ins_code_1: string, - auth_asym_id_2: string, - auth_seq_id_2: number, - label_comp_id_2: string, - label_alt_id_2: string, - PDB_ins_code_2: string, - confal_score: number, - NtC: string, - rmsd: number, - } - - export type MappedChains = Map<string, MappedResidues>; - export type MappedResidues = Map<number, number[]>; - - export interface Steps { - steps: Array<Step>, - mapping: MappedChains[], - } - - export interface HalfPyramid { - step: Step, - isLower: boolean, - } - - export interface Location extends DataLocation<HalfPyramid, {}> {} - - export function Location(step: Step, isLower: boolean) { - return DataLocation(DataTag, { step, isLower }, {}); + export function Location(step: DnatcoTypes.Step, isLower: boolean) { + return DataLocation(DnatcoTypes.DataTag, { step, isLower }, {}); } export function isLocation(x: any): x is Location { - return !!x && x.kind === 'data-location' && x.tag === DataTag; + return !!x && x.kind === 'data-location' && x.tag === DnatcoTypes.DataTag; } - export interface Loci extends DataLoci<HalfPyramid, {}> {} + export interface Loci extends DataLoci<DnatcoTypes.HalfStep, {}> {} - export function Loci(data: HalfPyramid, elements: ReadonlyArray<{}>): Loci { - return DataLoci(DataTag, data, elements, undefined, () => confalPyramidLabel(data)); + export function Loci(data: DnatcoTypes.HalfStep, elements: ReadonlyArray<{}>): Loci { + return DataLoci(DnatcoTypes.DataTag, data, elements, undefined, () => confalPyramidLabel(data)); } export function isLoci(x: any): x is Loci { - return !!x && x.kind === 'data-loci' && x.tag === DataTag; + return !!x && x.kind === 'data-loci' && x.tag === DnatcoTypes.DataTag; } } diff --git a/src/extensions/dnatco/confal-pyramids/util.ts b/src/extensions/dnatco/confal-pyramids/util.ts index af4e9793f259d202a52ccb0b896c7156bea87ae4..6dc100cab5c3f66fd43c7b6bb66182b5cb1038f4 100644 --- a/src/extensions/dnatco/confal-pyramids/util.ts +++ b/src/extensions/dnatco/confal-pyramids/util.ts @@ -6,11 +6,10 @@ */ import { ConfalPyramidsProvider } from './property'; -import { ConfalPyramidsTypes as CPT } from './types'; +import { DnatcoTypes } from '../types'; +import { DnatcoUtil } from '../util'; import { Segmentation } from '../../../mol-data/int'; -import { ChainIndex, ElementIndex, ResidueIndex, Structure, StructureElement, StructureProperties, Unit } from '../../../mol-model/structure'; - -type Residue = Segmentation.Segment<ResidueIndex>; +import { ChainIndex, ElementIndex, ResidueIndex, Structure, StructureElement, Unit } from '../../../mol-model/structure'; export type Pyramid = { O3: ElementIndex, @@ -22,31 +21,12 @@ export type Pyramid = { stepIdx: number, }; -const EmptyStepIndices = new Array<number>(); - -function copyResidue(r?: Residue) { - return r ? { index: r.index, start: r.start, end: r.end } : void 0; -} - -function getAtomIndex(loc: StructureElement.Location, residue: Residue, names: string[], altId: string): ElementIndex { - for (let eI = residue.start; eI < residue.end; eI++) { - loc.element = loc.unit.elements[eI]; - const elName = StructureProperties.atom.label_atom_id(loc); - const elAltId = StructureProperties.atom.label_alt_id(loc); - - if (names.includes(elName) && (elAltId === altId || elAltId.length === 0)) - return loc.element; - } - - return -1 as ElementIndex; -} - -function getPyramid(loc: StructureElement.Location, one: Residue, two: Residue, altIdOne: string, altIdTwo: string, confalScore: number, stepIdx: number): Pyramid { - const O3 = getAtomIndex(loc, one, ['O3\'', 'O3*'], altIdOne); - const P = getAtomIndex(loc, two, ['P'], altIdTwo); - const OP1 = getAtomIndex(loc, two, ['OP1'], altIdTwo); - const OP2 = getAtomIndex(loc, two, ['OP2'], altIdTwo); - const O5 = getAtomIndex(loc, two, ['O5\'', 'O5*'], altIdTwo); +function getPyramid(loc: StructureElement.Location, one: DnatcoUtil.Residue, two: DnatcoUtil.Residue, altIdOne: string, altIdTwo: string, confalScore: number, stepIdx: number): Pyramid { + const O3 = DnatcoUtil.getAtomIndex(loc, one, ['O3\'', 'O3*'], altIdOne); + const P = DnatcoUtil.getAtomIndex(loc, two, ['P'], altIdTwo); + const OP1 = DnatcoUtil.getAtomIndex(loc, two, ['OP1'], altIdTwo); + const OP2 = DnatcoUtil.getAtomIndex(loc, two, ['OP2'], altIdTwo); + const O5 = DnatcoUtil.getAtomIndex(loc, two, ['O5\'', 'O5*'], altIdTwo); return { O3, P, OP1, OP2, O5, confalScore, stepIdx }; } @@ -54,34 +34,20 @@ function getPyramid(loc: StructureElement.Location, one: Residue, two: Residue, export class ConfalPyramidsIterator { private chainIt: Segmentation.SegmentIterator<ChainIndex>; private residueIt: Segmentation.SegmentIterator<ResidueIndex>; - private residueOne?: Residue; - private residueTwo: Residue; - private data?: CPT.Steps; + private residueOne?: DnatcoUtil.Residue; + private residueTwo: DnatcoUtil.Residue; + private data?: DnatcoTypes.Steps; private loc: StructureElement.Location; - private getStepIndices(r: Residue) { - this.loc.element = this.loc.unit.elements[r.start]; - - const modelIdx = StructureProperties.unit.model_num(this.loc) - 1; - const chainId = StructureProperties.chain.auth_asym_id(this.loc); - const seqId = StructureProperties.residue.auth_seq_id(this.loc); - - const chains = this.data!.mapping[modelIdx]; - if (!chains) return EmptyStepIndices; - const residues = chains.get(chainId); - if (!residues) return EmptyStepIndices; - return residues.get(seqId) ?? EmptyStepIndices; - } - private moveStep() { - this.residueOne = copyResidue(this.residueTwo); - this.residueTwo = copyResidue(this.residueIt.move())!; + this.residueOne = DnatcoUtil.copyResidue(this.residueTwo); + this.residueTwo = DnatcoUtil.copyResidue(this.residueIt.move())!; return this.toPyramids(this.residueOne!, this.residueTwo); } - private toPyramids(one: Residue, two: Residue) { - const indices = this.getStepIndices(one); + private toPyramids(one: DnatcoUtil.Residue, two: DnatcoUtil.Residue) { + const indices = DnatcoUtil.getStepIndices(this.data!, this.loc, one); const points = []; for (const idx of indices) { diff --git a/src/extensions/dnatco/property.ts b/src/extensions/dnatco/property.ts new file mode 100644 index 0000000000000000000000000000000000000000..6af9c995d4223080285ddbc431532b751d396545 --- /dev/null +++ b/src/extensions/dnatco/property.ts @@ -0,0 +1,172 @@ +/** + * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Michal Malý <michal.maly@ibt.cas.cz> + * @author Jiřà Černý <jiri.cerny@ibt.cas.cz> + */ + +import { DnatcoTypes } from './types'; +import { Column, Table } from '../../mol-data/db'; +import { toTable } from '../../mol-io/reader/cif/schema'; +import { Model } from '../../mol-model/structure'; +import { CustomProperty } from '../../mol-model-props/common/custom-property'; +import { PropertyWrapper } from '../../mol-model-props/common/wrapper'; +import { MmcifFormat } from '../../mol-model-formats/structure/mmcif'; +import { ParamDefinition as PD } from '../../mol-util/param-definition'; + +export type DnatcoSteps = PropertyWrapper<DnatcoTypes.Steps | undefined>; + +export const DnatcoParams = {}; +export type DnatcoParams = typeof DnatcoParams; +export type DnatcoProps = PD.Values<DnatcoParams>; + +export namespace Dnatco { + export const Schema = { + ndb_struct_ntc_step: { + id: Column.Schema.int, + name: Column.Schema.str, + PDB_model_number: Column.Schema.int, + label_entity_id_1: Column.Schema.int, + label_asym_id_1: Column.Schema.str, + label_seq_id_1: Column.Schema.int, + label_comp_id_1: Column.Schema.str, + label_alt_id_1: Column.Schema.str, + label_entity_id_2: Column.Schema.int, + label_asym_id_2: Column.Schema.str, + label_seq_id_2: Column.Schema.int, + label_comp_id_2: Column.Schema.str, + label_alt_id_2: Column.Schema.str, + auth_asym_id_1: Column.Schema.str, + auth_seq_id_1: Column.Schema.int, + auth_asym_id_2: Column.Schema.str, + auth_seq_id_2: Column.Schema.int, + PDB_ins_code_1: Column.Schema.str, + PDB_ins_code_2: Column.Schema.str, + }, + ndb_struct_ntc_step_summary: { + step_id: Column.Schema.int, + assigned_CANA: Column.Schema.str, + assigned_NtC: Column.Schema.str, + confal_score: Column.Schema.int, + euclidean_distance_NtC_ideal: Column.Schema.float, + cartesian_rmsd_closest_NtC_representative: Column.Schema.float, + closest_CANA: Column.Schema.str, + closest_NtC: Column.Schema.str, + closest_step_golden: Column.Schema.str + } + }; + export type Schema = typeof Schema; + + export async function fromCif(ctx: CustomProperty.Context, model: Model, props: DnatcoProps): Promise<CustomProperty.Data<DnatcoSteps>> { + const info = PropertyWrapper.createInfo(); + const data = getCifData(model); + if (data === undefined) return { value: { info, data: undefined } }; + + const fromCif = createPyramidsFromCif(model, data.steps, data.stepsSummary); + return { value: { info, data: fromCif } }; + } + + function getCifData(model: Model) { + if (!MmcifFormat.is(model.sourceData)) throw new Error('Data format must be mmCIF'); + if (!hasNdbStructNtcCategories(model)) return undefined; + return { + steps: toTable(Schema.ndb_struct_ntc_step, model.sourceData.data.frame.categories.ndb_struct_ntc_step), + stepsSummary: toTable(Schema.ndb_struct_ntc_step_summary, model.sourceData.data.frame.categories.ndb_struct_ntc_step_summary) + }; + } + + function hasNdbStructNtcCategories(model: Model): boolean { + if (!MmcifFormat.is(model.sourceData)) return false; + const names = (model.sourceData).data.frame.categoryNames; + return names.includes('ndb_struct_ntc_step') && names.includes('ndb_struct_ntc_step_summary'); + } + + export function isApplicable(model?: Model): boolean { + return !!model && hasNdbStructNtcCategories(model); + } +} + +type StepsSummaryTable = Table<typeof Dnatco.Schema.ndb_struct_ntc_step_summary>; + +function createPyramidsFromCif( + model: Model, + cifSteps: Table<typeof Dnatco.Schema.ndb_struct_ntc_step>, + stepsSummary: StepsSummaryTable +): DnatcoTypes.Steps { + const steps = new Array<DnatcoTypes.Step>(); + const mapping = new Array<DnatcoTypes.MappedChains>(); + + const { + id, PDB_model_number, name, + auth_asym_id_1, auth_seq_id_1, label_comp_id_1, label_alt_id_1, PDB_ins_code_1, + auth_asym_id_2, auth_seq_id_2, label_comp_id_2, label_alt_id_2, PDB_ins_code_2, + _rowCount + } = cifSteps; + + if (_rowCount !== stepsSummary._rowCount) throw new Error('Inconsistent mmCIF data'); + + for (let i = 0; i < _rowCount; i++) { + const { + NtC, + confal_score, + rmsd + } = getSummaryData(id.value(i), i, stepsSummary); + const modelNum = PDB_model_number.value(i); + const chainId = auth_asym_id_1.value(i); + const seqId = auth_seq_id_1.value(i); + const modelIdx = modelNum - 1; + + if (mapping.length <= modelIdx || !mapping[modelIdx]) + mapping[modelIdx] = new Map<string, DnatcoTypes.MappedResidues>(); + + const step = { + PDB_model_number: modelNum, + name: name.value(i), + auth_asym_id_1: chainId, + auth_seq_id_1: seqId, + label_comp_id_1: label_comp_id_1.value(i), + label_alt_id_1: label_alt_id_1.value(i), + PDB_ins_code_1: PDB_ins_code_1.value(i), + auth_asym_id_2: auth_asym_id_2.value(i), + auth_seq_id_2: auth_seq_id_2.value(i), + label_comp_id_2: label_comp_id_2.value(i), + label_alt_id_2: label_alt_id_2.value(i), + PDB_ins_code_2: PDB_ins_code_2.value(i), + confal_score, + NtC, + rmsd, + }; + + steps.push(step); + + const mappedChains = mapping[modelIdx]; + const residuesOnChain = mappedChains.get(chainId) ?? new Map<number, number[]>(); + const stepsForResidue = residuesOnChain.get(seqId) ?? []; + stepsForResidue.push(steps.length - 1); + + residuesOnChain.set(seqId, stepsForResidue); + mappedChains.set(chainId, residuesOnChain); + mapping[modelIdx] = mappedChains; + } + + return { steps, mapping }; +} + +function getSummaryData(id: number, i: number, stepsSummary: StepsSummaryTable) { + const { + step_id, + confal_score, + assigned_NtC, + cartesian_rmsd_closest_NtC_representative, + } = stepsSummary; + + // Assume that step_ids in ntc_step_summary are in the same order as steps in ntc_step + for (let j = i; j < stepsSummary._rowCount; j++) { + if (id === step_id.value(j)) return { NtC: assigned_NtC.value(j), confal_score: confal_score.value(j), rmsd: cartesian_rmsd_closest_NtC_representative.value(j) }; + } + // Safety net for cases where the previous assumption is not met + for (let j = 0; j < i; j++) { + if (id === step_id.value(j)) return { NtC: assigned_NtC.value(j), confal_score: confal_score.value(j), rmsd: cartesian_rmsd_closest_NtC_representative.value(j) }; + } + throw new Error('Inconsistent mmCIF data'); +} diff --git a/src/extensions/dnatco/types.ts b/src/extensions/dnatco/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..ac8cb475a934c3242cd051902018a8b34484508f --- /dev/null +++ b/src/extensions/dnatco/types.ts @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Michal Malý <michal.maly@ibt.cas.cz> + * @author Jiřà Černý <jiri.cerny@ibt.cas.cz> + */ + +export namespace DnatcoTypes { + export const DataTag = 'dnatco-confal-half-step'; + + export type Step = { + PDB_model_number: number, + name: string, + auth_asym_id_1: string, + auth_seq_id_1: number, + label_comp_id_1: string, + label_alt_id_1: string, + PDB_ins_code_1: string, + auth_asym_id_2: string, + auth_seq_id_2: number, + label_comp_id_2: string, + label_alt_id_2: string, + PDB_ins_code_2: string, + confal_score: number, + NtC: string, + rmsd: number, + } + + export type MappedChains = Map<string, MappedResidues>; + export type MappedResidues = Map<number, number[]>; + + export interface Steps { + steps: Array<Step>, + mapping: MappedChains[], + } + + export interface HalfStep { + step: Step, + isLower: boolean, + } +} diff --git a/src/extensions/dnatco/util.ts b/src/extensions/dnatco/util.ts new file mode 100644 index 0000000000000000000000000000000000000000..0db2e9dec70d84fc56846f4d2b2c9e133cf5e4c6 --- /dev/null +++ b/src/extensions/dnatco/util.ts @@ -0,0 +1,40 @@ +import { DnatcoTypes } from './types'; +import { Segmentation } from '../../mol-data/int'; +import { ElementIndex, ResidueIndex, StructureElement, StructureProperties } from '../../mol-model/structure'; + +const EmptyStepIndices = new Array<number>(); + +export namespace DnatcoUtil { + export type Residue = Segmentation.Segment<ResidueIndex>; + + export function copyResidue(r?: Residue) { + return r ? { index: r.index, start: r.start, end: r.end } : void 0; + } + + export function getAtomIndex(loc: StructureElement.Location, residue: Residue, names: string[], altId: string): ElementIndex { + for (let eI = residue.start; eI < residue.end; eI++) { + loc.element = loc.unit.elements[eI]; + const elName = StructureProperties.atom.label_atom_id(loc); + const elAltId = StructureProperties.atom.label_alt_id(loc); + + if (names.includes(elName) && (elAltId === altId || elAltId.length === 0)) + return loc.element; + } + + return -1 as ElementIndex; + } + + export function getStepIndices(data: DnatcoTypes.Steps, loc: StructureElement.Location, r: DnatcoUtil.Residue) { + loc.element = loc.unit.elements[r.start]; + + const modelIdx = StructureProperties.unit.model_num(loc) - 1; + const chainId = StructureProperties.chain.auth_asym_id(loc); + const seqId = StructureProperties.residue.auth_seq_id(loc); + + const chains = data.mapping[modelIdx]; + if (!chains) return EmptyStepIndices; + const residues = chains.get(chainId); + if (!residues) return EmptyStepIndices; + return residues.get(seqId) ?? EmptyStepIndices; + } +}