Browse Source

chemCompBond creation improvements and prop

Alexander Rose 5 years ago
parent
commit
bf81b902bd

+ 1 - 1
README.md

@@ -95,7 +95,7 @@ Install CIFTools `npm install ciftools -g`
 ### Other scripts
 **Create chem comp bond table**
 
-    export NODE_PATH="lib"; node --max-old-space-size=8192 build/src/apps/chem-comp-bond/create-table.js build/data/ccb.bcif -b
+    export NODE_PATH="lib"; node --max-old-space-size=4096 lib/apps/chem-comp-bond/create-table.js build/data/ccb.bcif -b
 
 **Test model server**
 

+ 9 - 15
src/apps/chem-comp-bond/create-table.ts

@@ -1,5 +1,5 @@
 /**
- * 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>
  */
@@ -15,12 +15,13 @@ const readFile = util.promisify(fs.readFile)
 const writeFile = util.promisify(fs.writeFile)
 
 import { Progress } from '../../mol-task'
-import { Database, Table, DatabaseCollection, Column } from '../../mol-data/db'
+import { Database, Table, DatabaseCollection } from '../../mol-data/db'
 import { CIF } from '../../mol-io/reader/cif'
 import { CifWriter } from '../../mol-io/writer/cif'
 import { CCD_Schema } from '../../mol-io/reader/cif/schema/ccd'
 import { SetUtils } from '../../mol-util/set'
 import { DefaultMap } from '../../mol-util/map'
+import { mmCIF_chemCompBond_schema } from '../../mol-io/reader/cif/schema/mmcif-extras';
 
 export async function ensureAvailable(path: string, url: string) {
     if (FORCE_DOWNLOAD || !fs.existsSync(path)) {
@@ -74,16 +75,6 @@ export function getEncodedCif(name: string, database: Database<Database.Schema>,
 type CCB = Table<CCD_Schema['chem_comp_bond']>
 type CCA = Table<CCD_Schema['chem_comp_atom']>
 
-const ChemCompBond_Schema = {
-    comp_id: CCD_Schema['chem_comp_bond'].comp_id,
-    atom_id_1: CCD_Schema['chem_comp_bond'].atom_id_1,
-    atom_id_2: CCD_Schema['chem_comp_bond'].atom_id_2,
-    value_order: CCD_Schema['chem_comp_bond'].value_order,
-    pdbx_aromatic_flag: CCD_Schema['chem_comp_bond'].pdbx_aromatic_flag,
-    pdbx_stereo_config: CCD_Schema['chem_comp_bond'].pdbx_stereo_config,
-    molstar_protonation_variant: Column.Schema.Str()
-}
-
 function ccbKey(compId: string, atomId1: string, atomId2: string) {
     return atomId1 < atomId2 ? `${compId}:${atomId1}-${atomId2}` : `${compId}:${atomId2}-${atomId1}`
 }
@@ -202,14 +193,14 @@ async function createBonds() {
         }
     }
 
-    const bondTable = Table.ofArrays(ChemCompBond_Schema, {
+    const bondTable = Table.ofArrays(mmCIF_chemCompBond_schema, {
         comp_id, atom_id_1, atom_id_2, value_order,
         pdbx_aromatic_flag, pdbx_stereo_config, molstar_protonation_variant
     })
 
     const bondDatabase =  Database.ofTables(
         TABLE_NAME,
-        { chem_comp_bond: ChemCompBond_Schema },
+        { chem_comp_bond: mmCIF_chemCompBond_schema },
         { chem_comp_bond: bondTable }
     )
 
@@ -220,12 +211,15 @@ async function run(out: string, binary = false) {
     const bonds = await createBonds()
 
     const cif = getEncodedCif(TABLE_NAME, bonds, binary)
+    if (!fs.existsSync(path.dirname(out))) {
+        fs.mkdirSync(path.dirname(out));
+    }
     writeFile(out, cif)
 }
 
 const TABLE_NAME = 'CHEM_COMP_BONDS'
 
-const DATA_DIR = path.join(__dirname, '..', '..', '..', 'data')
+const DATA_DIR = path.join(__dirname, '..', '..', '..', 'build/data')
 const CCD_PATH = path.join(DATA_DIR, 'components.cif')
 const PVCD_PATH = path.join(DATA_DIR, 'aa-variants-v1.cif')
 const CCD_URL = 'http://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif'

+ 10 - 2
src/mol-io/reader/cif/schema/mmcif-extras.ts

@@ -1,10 +1,12 @@
 /**
- * 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 David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
- import { mmCIF_Schema } from './mmcif';
+import { mmCIF_Schema } from './mmcif';
+import { Column } from '../../../../mol-data/db';
 
 export const mmCIF_residueId_schema = {
     label_comp_id: mmCIF_Schema.atom_site.label_comp_id,
@@ -15,4 +17,10 @@ export const mmCIF_residueId_schema = {
     auth_comp_id: mmCIF_Schema.atom_site.auth_atom_id,
     auth_seq_id: mmCIF_Schema.atom_site.auth_seq_id,
     auth_asym_id: mmCIF_Schema.atom_site.auth_asym_id
+}
+
+export const mmCIF_chemCompBond_schema = {
+    ...mmCIF_Schema.chem_comp_bond,
+    /** Indicates if the bond entry was taken from the protonation variant dictionary */
+    molstar_protonation_variant: Column.Schema.Str()
 }

+ 84 - 0
src/mol-model-props/wwpdb/chem-comp-bond.ts

@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Column, Table } from '../../mol-data/db';
+import { toTable } from '../../mol-io/reader/cif/schema';
+import { Model, CustomPropertyDescriptor } from '../../mol-model/structure';
+import { mmCIF_chemCompBond_schema } from '../../mol-io/reader/cif/schema/mmcif-extras';
+import { CifWriter } from '../../mol-io/writer/cif';
+
+export namespace ChemCompBond {
+    export type Property = Table<Schema['chem_comp_bond']>
+
+    export function getFromModel(model: Model): Property {
+        if (model.sourceData.kind !== 'mmCIF') return Table.ofUndefinedColumns(Schema.chem_comp_bond, 0);
+        const { chem_comp_bond } = model.sourceData.data
+        return Table.ofColumns(Schema.chem_comp_bond, {
+            ...chem_comp_bond,
+            molstar_protonation_variant: Column.Undefined(chem_comp_bond._rowCount, Column.Schema.Str())
+        });
+    }
+
+    export function get(model: Model): Property {
+        return model._staticPropertyData.__ChemCompBond__ || getFromModel(model);
+    }
+    function set(model: Model, prop: Property) {
+        (model._staticPropertyData.__ChemCompBond__ as Property) = prop;
+    }
+
+    export const Schema = { chem_comp_bond: mmCIF_chemCompBond_schema };
+    export type Schema = typeof Schema
+
+    export const Descriptor = CustomPropertyDescriptor({
+        isStatic: true,
+        name: 'chem_comp_bond',
+        cifExport: {
+            prefix: '',
+            context(ctx): Property { return get(ctx.firstModel); },
+            categories: [{
+                name: 'chem_comp_bond',
+                instance(ctx: Property) {
+                    return CifWriter.Category.ofTable(ctx);
+                }
+            }]
+        }
+    });
+
+    function fromCifData(model: Model): Table<Schema['chem_comp_bond']> | undefined {
+        if (model.sourceData.kind !== 'mmCIF') return void 0;
+        const cat = model.sourceData.frame.categories.chem_comp_bond;
+        if (!cat) return void 0;
+        return toTable(Schema.chem_comp_bond, cat);
+    }
+
+    export async function attachFromCifOrTable(model: Model, params: {
+        // optional Table source
+        wwPDB_apiSourceTable?: (model: Model) => Promise<Table<Schema['chem_comp_bond']>>
+    }) {
+        if (model.customProperties.has(Descriptor)) return true;
+
+        let chemCompBond: Table<Schema['chem_comp_bond']> | undefined = fromCifData(model);
+        if (chemCompBond === void 0 && params.wwPDB_apiSourceTable) {
+            const data = await params.wwPDB_apiSourceTable(model);
+            if (!data) return false;
+            chemCompBond = chemCompBondFromTable(model, data);
+        } else {
+            return false;
+        }
+
+        if (!chemCompBond) return false;
+
+        model.customProperties.add(Descriptor);
+        set(model, chemCompBond);
+        return true;
+    }
+}
+
+function chemCompBondFromTable(model: Model, table: Table<ChemCompBond.Schema['chem_comp_bond']>): Table<ChemCompBond.Schema['chem_comp_bond']> {
+    return Table.pick(table, ChemCompBond.Schema.chem_comp_bond, (i: number) => {
+        return model.properties.chemicalComponentMap.has(table.comp_id.value(i))
+    })
+}