/** * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal * @author Alexander Rose */ /** * Copyright (C) 2022, Protein Bioinformatics Research Group, RCNS * * Licensed under CC BY-NC 4.0, see LICENSE file for more info. * * @author Gabor Tusnady * @author Csongor Gerdan */ import { ParamDefinition as PD } from 'molstar/lib/mol-util/param-definition'; import { Structure, StructureProperties, Unit } from 'molstar/lib/mol-model/structure'; import { CustomPropertyDescriptor } from 'molstar/lib/mol-model/custom-property'; import { isInMembranePlane, TMDETParams } from './algorithm'; import { CustomStructureProperty } from 'molstar/lib/mol-model-props/common/custom-structure-property'; import { CustomProperty } from 'molstar/lib/mol-model-props/common/custom-property'; import { Vec3 } from 'molstar/lib/mol-math/linear-algebra'; import { QuerySymbolRuntime } from 'molstar/lib/mol-script/runtime/query/base'; import { CustomPropSymbol } from 'molstar/lib/mol-script/language/symbol'; import { Type } from 'molstar/lib/mol-script/language/type'; import { membraneOrientation } from './behavior'; import { ChainList, PDBTMDescriptor } from './types'; export const MembraneOrientationParams = { ...TMDETParams }; export type MembraneOrientationParams = typeof MembraneOrientationParams export type MembraneOrientationProps = PD.Values export { MembraneOrientation }; /** * Simple storage to made PDBTM descriptor available globally. * * @author Csongor Gerdan */ class DescriptorCache { private map: Map; constructor() { this.map = new Map(); } add(descriptor: PDBTMDescriptor) { const key = descriptor.pdb_id.toLowerCase(); if (!this.map.has(key)) { this.map.set(key, descriptor); } } get(key: string) { key = key.toLowerCase(); return this.map.get(key); } } export const TmDetDescriptorCache = new DescriptorCache(); class ChainListCache { private map: Map; constructor() { this.map = new Map(); } set(key: string, chains: ChainList) { key = key.toLowerCase(); if (!this.map.has(key)) { this.map.set(key, chains); } } get(key: string) { key = key.toLowerCase(); return this.map.get(key); } } export const TmDetChainListCache = new ChainListCache(); interface MembraneOrientation { // point in membrane boundary readonly planePoint1: Vec3, // point in opposite side of membrane boundary readonly planePoint2: Vec3, // normal vector of membrane layer readonly normalVector: Vec3, // the radius of the membrane layer readonly radius: number, readonly centroid: Vec3 } namespace MembraneOrientation { export enum Tag { Representation = 'membrane-orientation-3d' } const pos = Vec3(); export const symbols = { isTransmembrane: QuerySymbolRuntime.Dynamic(CustomPropSymbol('computed', 'membrane-orientation.is-transmembrane', Type.Bool), ctx => { const { unit, structure } = ctx.element; const { x, y, z } = StructureProperties.atom; if (!Unit.isAtomic(unit)) return 0; const membraneOrientation = MembraneOrientationProvider.get(structure).value; if (!membraneOrientation) return 0; Vec3.set(pos, x(ctx.element), y(ctx.element), z(ctx.element)); const { normalVector, planePoint1, planePoint2 } = membraneOrientation; return isInMembranePlane(pos, normalVector, planePoint1, planePoint2); }) }; } export const MembraneOrientationProvider: CustomStructureProperty.Provider = CustomStructureProperty.createProvider({ label: 'TMDET Membrane Orientation Provider', descriptor: CustomPropertyDescriptor({ name: 'tmdet_computed_membrane_orientation', symbols: MembraneOrientation.symbols, // TODO `cifExport` }), type: 'root', defaultParams: MembraneOrientationParams, // getParams: (data: Structure) => MembraneOrientationParams, getParams: function(data: Structure) { //DebugUtil.log('getParams:: DEBUG', MembraneOrientationParams); return MembraneOrientationParams; }, isApplicable: (data: Structure) => true, obtain: async (ctx: CustomProperty.Context, data: Structure, props: Partial) => { //DebugUtil.log('obtain:: DEBUG', data.customPropertyDescriptors); let result = membraneOrientation; //DebugUtil.log("RESULT of 'obtain:'", result); return { value: result }; } });