From 5fcf27eb71d221e6641d7298e59dabd63f1fc659 Mon Sep 17 00:00:00 2001
From: Alexander Rose <alexander.rose@weirdbyte.de>
Date: Sat, 24 Nov 2018 19:07:16 -0800
Subject: [PATCH] check for carb comps before calculating carbs

---
 src/mol-model/structure/model/formats/mmcif.ts    | 15 ++++++++++-----
 .../structure/structure/carbohydrates/compute.ts  |  6 +++++-
 .../structure/structure/carbohydrates/data.ts     | 14 ++++++++++++++
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/mol-model/structure/model/formats/mmcif.ts b/src/mol-model/structure/model/formats/mmcif.ts
index ca0cb9405..d0684dcb4 100644
--- a/src/mol-model/structure/model/formats/mmcif.ts
+++ b/src/mol-model/structure/model/formats/mmcif.ts
@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2018 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>
  */
 
 import { Column, Table } from 'mol-data/db';
@@ -112,7 +113,7 @@ function getSaccharideComponentMap(format: mmCIF_Format): SaccharideComponentMap
     const map = new Map<string, SaccharideComponent>();
     const { pdbx_chem_comp_identifier } = format.data
     if (pdbx_chem_comp_identifier._rowCount > 0) {
-        const { type, comp_id, identifier } = pdbx_chem_comp_identifier
+        const { comp_id, type, identifier } = pdbx_chem_comp_identifier
         for (let i = 0, il = pdbx_chem_comp_identifier._rowCount; i < il; ++i) {
             if (type.value(i) === 'SNFG CARB SYMBOL') {
                 const snfgName = identifier.value(i)
@@ -124,16 +125,20 @@ function getSaccharideComponentMap(format: mmCIF_Format): SaccharideComponentMap
                 }
             }
         }
-    } else {
-        SaccharideCompIdMap.forEach((v, k) => map.set(k, v))
+    } else if (format.data.chem_comp._rowCount > 0) {
         const { id, type  } = format.data.chem_comp
         for (let i = 0, il = id.rowCount; i < il; ++i) {
             const _id = id.value(i)
             const _type = type.value(i)
-            if (!map.has(_id) && getMoleculeType(_type, _id) === MoleculeType.saccharide) {
+            if (SaccharideCompIdMap.has(_id)) {
+                map.set(_id, SaccharideCompIdMap.get(_id)!)
+            } else if (!map.has(_id) && getMoleculeType(_type, _id) === MoleculeType.saccharide) {
                 map.set(_id, UnknownSaccharideComponent)
             }
         }
+    } else {
+        // TODO check if present in format.data.atom_site.label_comp_id
+        SaccharideCompIdMap.forEach((v, k) => map.set(k, v))
     }
     return map
 }
diff --git a/src/mol-model/structure/structure/carbohydrates/compute.ts b/src/mol-model/structure/structure/carbohydrates/compute.ts
index e621cbc22..8fc4688a5 100644
--- a/src/mol-model/structure/structure/carbohydrates/compute.ts
+++ b/src/mol-model/structure/structure/carbohydrates/compute.ts
@@ -17,7 +17,7 @@ import { getPositionMatrix } from '../../util';
 import StructureElement from '../element';
 import Structure from '../structure';
 import Unit from '../unit';
-import { CarbohydrateElement, CarbohydrateLink, Carbohydrates, CarbohydrateTerminalLink, PartialCarbohydrateElement } from './data';
+import { CarbohydrateElement, CarbohydrateLink, Carbohydrates, CarbohydrateTerminalLink, PartialCarbohydrateElement, EmptyCarbohydrates } from './data';
 import { UnitRings, UnitRing } from '../unit/rings';
 import { ElementIndex } from '../../model/indexing';
 
@@ -122,6 +122,10 @@ function getSaccharideComp(compId: string, model: Model) {
 }
 
 export function computeCarbohydrates(structure: Structure): Carbohydrates {
+    // skip computation if there are no saccharide components in any model
+    if (structure.models.reduce((a, v) => a + v.properties.saccharideComponentMap.size, 0) === 0)
+        return EmptyCarbohydrates
+
     const links: CarbohydrateLink[] = []
     const terminalLinks: CarbohydrateTerminalLink[] = []
     const elements: CarbohydrateElement[] = []
diff --git a/src/mol-model/structure/structure/carbohydrates/data.ts b/src/mol-model/structure/structure/carbohydrates/data.ts
index 2528bdd6d..1eaae487c 100644
--- a/src/mol-model/structure/structure/carbohydrates/data.ts
+++ b/src/mol-model/structure/structure/carbohydrates/data.ts
@@ -50,4 +50,18 @@ export interface Carbohydrates {
     getTerminalLinkIndex: (unitA: Unit, elementA: ElementIndex, unitB: Unit, elementB: ElementIndex) => number | undefined
     getTerminalLinkIndices: (unit: Unit, element: ElementIndex) => ReadonlyArray<number>
     getAnomericCarbon: (unit: Unit, residueIndex: ResidueIndex) => ElementIndex | undefined
+}
+
+const EmptyArray: ReadonlyArray<any> = []
+export const EmptyCarbohydrates: Carbohydrates = {
+    links: EmptyArray,
+    terminalLinks: EmptyArray,
+    elements: EmptyArray,
+    partialElements: EmptyArray,
+    getElementIndex: () => undefined,
+    getLinkIndex: () => undefined,
+    getLinkIndices: () => EmptyArray,
+    getTerminalLinkIndex: () => undefined,
+    getTerminalLinkIndices: () => EmptyArray,
+    getAnomericCarbon: () => undefined,
 }
\ No newline at end of file
-- 
GitLab