Browse Source

ensure trace element for polymer residues

Alexander Rose 3 years ago
parent
commit
176f80ea9b

+ 7 - 1
src/mol-model/structure/model/properties/atomic/hierarchy.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -206,6 +206,12 @@ export interface AtomicIndex {
      */
     findAtomsOnResidue(residueIndex: ResidueIndex, label_atom_ids: Set<string>): ElementIndex
 
+    /**
+     * Find element index of an atom on a given residue.
+     * @returns index or -1 if the atom is not present.
+     */
+     findElementOnResidue(residueIndex: ResidueIndex, type_symbol: ElementSymbol): ElementIndex
+
     // TODO: add indices that support comp_id?
 }
 

+ 5 - 2
src/mol-model/structure/model/properties/utils/atomic-derived.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -7,7 +7,7 @@
 import { AtomicData, AtomNumber } from '../atomic';
 import { AtomicIndex, AtomicDerivedData, AtomicSegments } from '../atomic/hierarchy';
 import { ElementIndex, ResidueIndex } from '../../indexing';
-import { MoleculeType, getMoleculeType, getComponentType, PolymerType, getPolymerType } from '../../types';
+import { MoleculeType, getMoleculeType, getComponentType, PolymerType, getPolymerType, isPolymer, ElementSymbol } from '../../types';
 import { getAtomIdForAtomRole } from '../../../../../mol-model/structure/util';
 import { ChemicalComponentMap } from '../common';
 import { isProductionMode } from '../../../../../mol-util/debug';
@@ -63,6 +63,9 @@ export function getAtomicDerivedData(data: AtomicData, segments: AtomicSegments,
         if (traceIndex === -1) {
             const coarseAtomId = getAtomIdForAtomRole(polyType, 'coarseBackbone');
             traceIndex = index.findAtomsOnResidue(i, coarseAtomId);
+            if (traceIndex === -1 && isPolymer(molType)) {
+                traceIndex = index.findElementOnResidue(i, ElementSymbol('C'));
+            }
         }
         traceElementIndex[i] = traceIndex;
 

+ 15 - 1
src/mol-model/structure/model/properties/utils/atomic-index.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -12,6 +12,7 @@ import { ChainIndex, ResidueIndex, EntityIndex, ElementIndex } from '../../index
 import { AtomicIndex, AtomicHierarchy } from '../atomic/hierarchy';
 import { cantorPairing } from '../../../../../mol-data/util';
 import { Column } from '../../../../../mol-data/db';
+import { ElementSymbol } from '../../types';
 
 function getResidueId(seq_id: number, ins_code: string) {
     if (!ins_code) return seq_id;
@@ -43,6 +44,7 @@ interface Mapping {
     label_atom_id: Column<string>,
     auth_atom_id: Column<string>,
     label_alt_id: Column<string>,
+    type_symbol: Column<ElementSymbol>,
     segments: AtomicSegments,
 
     chain_index_entity_index: EntityIndex[],
@@ -64,6 +66,7 @@ function createMapping(entities: Entities, data: AtomicData, segments: AtomicSeg
         label_atom_id: data.atoms.label_atom_id,
         auth_atom_id: data.atoms.auth_atom_id,
         label_alt_id: data.atoms.label_alt_id,
+        type_symbol: data.atoms.type_symbol,
         chain_index_entity_index: new Int32Array(data.chains._rowCount) as any,
         entity_index_label_asym_id: new Map(),
         chain_index_label_seq_id: new Map(),
@@ -173,6 +176,10 @@ class Index implements AtomicIndex {
         return findAtomByNames(this.residueOffsets[rI], this.residueOffsets[rI + 1], this.map.label_atom_id, label_atom_ids);
     }
 
+    findElementOnResidue(rI: ResidueIndex, type_symbol: ElementSymbol) {
+        return findAtomByElement(this.residueOffsets[rI], this.residueOffsets[rI + 1], this.map.type_symbol, type_symbol);
+    }
+
     constructor(private map: Mapping) {
         this.entityIndex = map.entities.getEntityIndex;
         this.residueOffsets = this.map.segments.residueAtomSegments.offsets;
@@ -201,6 +208,13 @@ function findAtomByNameAndAltLoc(start: ElementIndex, end: ElementIndex, nameDat
     return -1 as ElementIndex;
 }
 
+function findAtomByElement(start: ElementIndex, end: ElementIndex, data: Column<ElementSymbol>, typeSymbol: ElementSymbol): ElementIndex {
+    for (let i = start; i < end; i++) {
+        if (data.value(i) === typeSymbol) return i;
+    }
+    return -1 as ElementIndex;
+}
+
 export function getAtomicIndex(data: AtomicData, entities: Entities, segments: AtomicSegments): AtomicIndex {
     const map = createMapping(entities, data, segments);