diff --git a/src/mol-model-formats/structure/mmcif/parser.ts b/src/mol-model-formats/structure/mmcif/parser.ts index 8a8e4012695ad8af3f777f8ea12e7bd1c6cb6c81..4a16920ba94f80923960add8ee65176df8d8eb66 100644 --- a/src/mol-model-formats/structure/mmcif/parser.ts +++ b/src/mol-model-formats/structure/mmcif/parser.ts @@ -23,8 +23,8 @@ import { getSecondaryStructureMmCif } from './secondary-structure'; import { getSequence } from './sequence'; import { sortAtomSite } from './sort'; import { StructConn } from './bonds/struct_conn'; -import { ChemicalComponent, ChemicalComponentMap } from 'mol-model/structure/model/properties/chemical-component'; -import { ComponentType, getMoleculeType, MoleculeType } from 'mol-model/structure/model/types'; +import { ChemicalComponent } from 'mol-model/structure/model/properties/chemical-component'; +import { getMoleculeType, MoleculeType } from 'mol-model/structure/model/types'; import { ModelFormat } from '../format'; import { SaccharideComponentMap, SaccharideComponent, SaccharidesSnfgMap, SaccharideCompIdMap, UnknownSaccharideComponent } from 'mol-model/structure/structure/carbohydrates/constants'; import mmCIF_Format = ModelFormat.mmCIF @@ -96,24 +96,13 @@ function getModifiedResidueNameMap(format: mmCIF_Format): Model['properties']['m return { parentId, details }; } -function getChemicalComponentMap(format: mmCIF_Format): ChemicalComponentMap { +function getChemicalComponentMap(format: mmCIF_Format): Model['properties']['chemicalComponentMap'] { const map = new Map<string, ChemicalComponent>(); const { chem_comp } = format.data if (chem_comp._rowCount > 0) { - const { id, type, name, pdbx_synonyms, formula, formula_weight } = format.data.chem_comp + const { id } = format.data.chem_comp for (let i = 0, il = id.rowCount; i < il; ++i) { - const _id = id.value(i) - const _type = type.value(i) - const cc: ChemicalComponent = { - id: _id, - type: ComponentType[_type], - moleculeType: getMoleculeType(_type, _id), - name: name.value(i), - synonyms: pdbx_synonyms.value(i), - formula: formula.value(i), - formulaWeight: formula_weight.value(i), - } - map.set(_id, cc) + map.set(id.value(i), Table.getRow(format.data.chem_comp, i)) } } return map diff --git a/src/mol-model/structure/model/model.ts b/src/mol-model/structure/model/model.ts index 9c44135df7b8e64b081ffa4c449622d0a4443635..c777d8d55fe61d75afc5b24f07e58dbfe0b4748e 100644 --- a/src/mol-model/structure/model/model.ts +++ b/src/mol-model/structure/model/model.ts @@ -12,9 +12,9 @@ import { CoarseHierarchy, CoarseConformation } from './properties/coarse'; import { Entities } from './properties/common'; import { CustomProperties } from './properties/custom'; import { SecondaryStructure } from './properties/seconday-structure'; -import { ChemicalComponentMap } from './properties/chemical-component'; import { SaccharideComponentMap } from '../structure/carbohydrates/constants'; import { ModelFormat } from 'mol-model-formats/structure/format'; +import { ChemicalComponentMap } from './properties/chemical-component'; /** * Interface to the "source data" of the molecule. diff --git a/src/mol-model/structure/model/properties/chemical-component.ts b/src/mol-model/structure/model/properties/chemical-component.ts index 35d34e571790872c8e1a110bc125705d7a4b49c4..15efa28fed123964a6f47efc6555f8343f6514c8 100644 --- a/src/mol-model/structure/model/properties/chemical-component.ts +++ b/src/mol-model/structure/model/properties/chemical-component.ts @@ -4,16 +4,10 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { MoleculeType, ComponentType } from '../types' +import { mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif'; +import { Table } from 'mol-data/db'; -export interface ChemicalComponent { - id: string - type: ComponentType - moleculeType: MoleculeType - name: string - synonyms: string[] - formula: string - formulaWeight: number -} +export type ChemicalComponent = Table.Row<mmCIF_Schema['chem_comp']> +export type ChemicalComponentMap = ReadonlyMap<string, ChemicalComponent> -export type ChemicalComponentMap = ReadonlyMap<string, ChemicalComponent> \ No newline at end of file +// TODO add data for common chemical components \ No newline at end of file diff --git a/src/mol-model/structure/model/properties/utils/atomic-derived.ts b/src/mol-model/structure/model/properties/utils/atomic-derived.ts index 5dcb94da5b0f869eee578eca33f241d1846c31af..f2e1833042eff059d102d7d25dd1d860eac8bce7 100644 --- a/src/mol-model/structure/model/properties/utils/atomic-derived.ts +++ b/src/mol-model/structure/model/properties/utils/atomic-derived.ts @@ -23,12 +23,12 @@ export function getAtomicDerivedData(data: AtomicData, index: AtomicIndex, chemi for (let i = 0; i < n; ++i) { const compId = label_comp_id.value(i) const chemCompMap = chemicalComponentMap - const cc = chemCompMap.get(compId) let molType: MoleculeType - if (cc) { - molType = cc.moleculeType - } else if (moleculeTypeMap.has(compId)){ + if (moleculeTypeMap.has(compId)){ molType = moleculeTypeMap.get(compId)! + } else if (chemCompMap.has(compId)) { + molType = getMoleculeType(chemCompMap.get(compId)!.type, compId) + moleculeTypeMap.set(compId, molType) } else { molType = getMoleculeType(getComponentType(compId), compId) // TODO if unknown molecule type, use atom names to guess molecule type diff --git a/src/mol-model/structure/model/types.ts b/src/mol-model/structure/model/types.ts index 20d44428bb70f4bbfcc9d7d7ea7990a172e3a4cd..3c1bb8383903c32ee2bc27479c3c727d662f755f 100644 --- a/src/mol-model/structure/model/types.ts +++ b/src/mol-model/structure/model/types.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author David Sehnal <david.sehnal@gmail.com> @@ -7,6 +7,7 @@ import BitFlags from 'mol-util/bit-flags' import { SaccharideCompIdMap } from '../structure/carbohydrates/constants'; +import { mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif'; const _esCache = (function () { const cache = Object.create(null); @@ -100,29 +101,6 @@ export const NucleicBackboneAtoms = [ 'O2*', 'O3*', 'O4*', 'O5*', 'C1*', 'C2*', 'C3*', 'C4*', 'C5*' ] -/** Chemical component types as defined in the mmCIF CCD */ -export enum ComponentType { - // protein - 'D-peptide linking', 'L-peptide linking', 'D-peptide NH3 amino terminus', - 'L-peptide NH3 amino terminus', 'D-peptide COOH carboxy terminus', - 'L-peptide COOH carboxy terminus', 'peptide linking', 'peptide-like', - 'L-gamma-peptide, C-delta linking', 'D-gamma-peptide, C-delta linking', - 'L-beta-peptide, C-gamma linking', 'D-beta-peptide, C-gamma linking', - - // DNA - 'DNA linking', 'L-DNA linking', 'DNA OH 5 prime terminus', 'DNA OH 3 prime terminus', - - // RNA - 'RNA linking', 'L-RNA linking', 'RNA OH 5 prime terminus', 'RNA OH 3 prime terminus', - - // sacharide - 'D-saccharide 1,4 and 1,4 linking', 'L-saccharide 1,4 and 1,4 linking', - 'D-saccharide 1,4 and 1,6 linking', 'L-saccharide 1,4 and 1,6 linking', 'L-saccharide', - 'D-saccharide', 'saccharide', - - 'non-polymer', 'other' -} - /** Chemical component type names for protein */ export const ProteinComponentTypeNames = [ 'D-PEPTIDE LINKING', 'L-PEPTIDE LINKING', 'D-PEPTIDE NH3 AMINO TERMINUS', @@ -221,7 +199,7 @@ export function getMoleculeType(compType: string, compId: string) { } } -export function getComponentType(compId: string) { +export function getComponentType(compId: string): mmCIF_Schema['chem_comp']['type']['T'] { compId = compId.toUpperCase() if (AminoAcidNames.includes(compId)) { return 'peptide linking' @@ -245,6 +223,8 @@ export function isNucleic(moleculeType: MoleculeType) { } /** + * TODO write script that read CCD and outputs list of ion names + * * all chemical components with the word "ion" in their name, Sep 2016 * * SET SESSION group_concat_max_len = 1000000; diff --git a/src/mol-model/structure/util.ts b/src/mol-model/structure/util.ts index e688b99c2c88325f541e5184020b98dd5648bcd8..40b5c13dac895a5a43e62a51aee243f932886054 100644 --- a/src/mol-model/structure/util.ts +++ b/src/mol-model/structure/util.ts @@ -1,11 +1,11 @@ /** - * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { Model, ResidueIndex, ElementIndex } from './model'; -import { MoleculeType, AtomRole, MoleculeTypeAtomRoleId } from './model/types'; +import { MoleculeType, AtomRole, MoleculeTypeAtomRoleId, getMoleculeType } from './model/types'; import { Vec3 } from 'mol-math/linear-algebra'; import { Unit } from './structure'; import Matrix from 'mol-math/linear-algebra/matrix/matrix'; @@ -17,27 +17,22 @@ export function getCoarseBegCompId(unit: Unit.Spheres | Unit.Gaussians, element: return seq.compId.value(seq_id_begin - 1) // 1-indexed } -export function getElementMoleculeType(unit: Unit, element: ElementIndex) { - let compId = '' +export function getElementMoleculeType(unit: Unit, element: ElementIndex): MoleculeType { switch (unit.kind) { case Unit.Kind.Atomic: - compId = unit.model.atomicHierarchy.residues.label_comp_id.value(unit.residueIndex[element]) - break + return unit.model.atomicHierarchy.derived.residue.moleculeType[unit.residueIndex[element]] case Unit.Kind.Spheres: case Unit.Kind.Gaussians: - compId = getCoarseBegCompId(unit, element) - break + // TODO add unit.model.coarseHierarchy.derived.residue.moleculeType + const compId = getCoarseBegCompId(unit, element) + const cc = unit.model.properties.chemicalComponentMap.get(compId) + if (cc) return getMoleculeType(cc.type, compId) } - const chemCompMap = unit.model.properties.chemicalComponentMap - const cc = chemCompMap.get(compId) - return cc ? cc.moleculeType : MoleculeType.unknown + return MoleculeType.unknown } -export function getAtomicMoleculeType(model: Model, rI: ResidueIndex) { - const compId = model.atomicHierarchy.residues.label_comp_id.value(rI) - const chemCompMap = model.properties.chemicalComponentMap - const cc = chemCompMap.get(compId) - return cc ? cc.moleculeType : MoleculeType.unknown +export function getAtomicMoleculeType(model: Model, rI: ResidueIndex): MoleculeType { + return model.atomicHierarchy.derived.residue.moleculeType[rI] } export function getAtomIdForAtomRole(moleculeType: MoleculeType, atomRole: AtomRole) { diff --git a/src/mol-plugin/behavior/dynamic/labels.ts b/src/mol-plugin/behavior/dynamic/labels.ts index 0faa3ffbd84254fac455c412c2e153fd3da2938f..7b8ccd1ba92cb413457de3fe1e6ae15b85944084 100644 --- a/src/mol-plugin/behavior/dynamic/labels.ts +++ b/src/mol-plugin/behavior/dynamic/labels.ts @@ -21,6 +21,7 @@ import { Unit, StructureElement, StructureProperties } from 'mol-model/structure import { SetUtils } from 'mol-util/set'; import { arrayEqual } from 'mol-util'; import { MoleculeType } from 'mol-model/structure/model/types'; +import { getElementMoleculeType } from 'mol-model/structure/util'; // TODO // - support more object types than structures @@ -157,9 +158,7 @@ export const SceneLabels = PluginBehavior.create<SceneLabelsProps>({ } if (p.levels.includes('ligand') && !u.polymerElements.length) { - const compId = StructureProperties.residue.label_comp_id(l) - const chemComp = u.model.properties.chemicalComponentMap.get(compId) - const moleculeType = chemComp ? chemComp.moleculeType : MoleculeType.unknown + const moleculeType = getElementMoleculeType(u, u.elements[0]) if (moleculeType === MoleculeType.other || moleculeType === MoleculeType.saccharide) { label = `${StructureProperties.entity.pdbx_description(l).join(', ')} (${getAsymId(u)(l)})` }