Skip to content
Snippets Groups Projects
Select Git revision
  • 29e8fe79049753d2ffacea532f000476f1d6a1d9
  • master default protected
  • rednatco-v2
  • base-pairs-ladder
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
41 results

query.ts

Blame
  • comp.ts 5.97 KiB
    /**
     * 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 { Model } from 'mol-model/structure/model/model'
    import { LinkType } from 'mol-model/structure/model/types'
    import { ModelPropertyDescriptor } from 'mol-model/structure/model/properties/custom';
    import { mmCIF_Database } from 'mol-io/reader/cif/schema/mmcif';
    import { Structure, Unit, StructureProperties, StructureElement } from 'mol-model/structure';
    import { Segmentation } from 'mol-data/int';
    import { CifWriter } from 'mol-io/writer/cif'
    
    export interface ComponentBond {
        entries: Map<string, ComponentBond.Entry>
    }
    
    export namespace ComponentBond {
        export const Descriptor: ModelPropertyDescriptor = {
            isStatic: true,
            name: 'chem_comp_bond',
            cifExport: {
                prefix: '',
                categories: [{
                    name: 'chem_comp_bond',
                    instance(ctx) {
                        const chem_comp_bond = getChemCompBond(ctx.structures[0].model);
                        if (!chem_comp_bond) return CifWriter.Category.Empty;
    
                        const comp_names = getUniqueResidueNames(ctx.structures[0]);
                        const { comp_id, _rowCount } = chem_comp_bond;
                        const indices: number[] = [];
                        for (let i = 0; i < _rowCount; i++) {
                            if (comp_names.has(comp_id.value(i))) indices[indices.length] = i;
                        }
    
                        return CifWriter.Category.ofTable(chem_comp_bond, indices)
                    }
                }]
            }
        }
    
        export function attachFromMmCif(model: Model): boolean {
            if (model.customProperties.has(Descriptor)) return true;
            if (model.sourceData.kind !== 'mmCIF') return false;
            const { chem_comp_bond } = model.sourceData.data;
            if (chem_comp_bond._rowCount === 0) return false;
    
            model.customProperties.add(Descriptor);
            model._staticPropertyData.__ComponentBondData__ = chem_comp_bond;
            return true;
        }
    
        export function attachFromExternalData(model: Model, bonds: ComponentBond, force = false) {
            if (!force && model.customProperties.has(Descriptor)) return true;
            if (model._staticPropertyData.__ComponentBondData__) delete model._staticPropertyData.__ComponentBondData__;
            model.customProperties.add(Descriptor);
            model._staticPropertyData[PropName] = bonds;
            return true;
        }
    
        export class ComponentBondImpl implements ComponentBond {
            entries: Map<string, ComponentBond.Entry> = new Map();
    
            addEntry(id: string) {
                let e = new Entry(id);
                this.entries.set(id, e);
                return e;
            }
        }
    
        export class Entry {
            map: Map<string, Map<string, { order: number, flags: number }>> = new Map();
    
            add(a: string, b: string, order: number, flags: number, swap = true) {
                let e = this.map.get(a);
                if (e !== void 0) {
                    let f = e.get(b);
                    if (f === void 0) {
                        e.set(b, { order, flags });
                    }
                } else {
                    let map = new Map<string, { order: number, flags: number }>();
                    map.set(b, { order, flags });
                    this.map.set(a, map);
                }
    
                if (swap) this.add(b, a, order, flags, false);
            }
    
            constructor(public id: string) {
            }
        }
    
        export function parseChemCompBond(data: mmCIF_Database['chem_comp_bond']): ComponentBond {
            const { comp_id, atom_id_1, atom_id_2, value_order, pdbx_aromatic_flag, _rowCount: rowCount } = data;
    
            const compBond = new ComponentBondImpl();
            let entry = compBond.addEntry(comp_id.value(0)!);
            for (let i = 0; i < rowCount; i++) {
                const id = comp_id.value(i)!;
                const nameA = atom_id_1.value(i)!;
                const nameB = atom_id_2.value(i)!;
                const order = value_order.value(i)!;
                const aromatic = pdbx_aromatic_flag.value(i) === 'Y';
    
                if (entry.id !== id) {
                    entry = compBond.addEntry(id);
                }
    
                let flags: number = LinkType.Flag.Covalent;
                let ord = 1;
                if (aromatic) flags |= LinkType.Flag.Aromatic;
                switch (order.toLowerCase()) {
                    case 'doub':
                    case 'delo':
                        ord = 2;
                        break;
                    case 'trip': ord = 3; break;
                    case 'quad': ord = 4; break;
                }
    
                entry.add(nameA, nameB, ord, flags);
            }
    
            return compBond;
        }
    
        function getChemCompBond(model: Model) {
            return model._staticPropertyData.__ComponentBondData__ as mmCIF_Database['chem_comp_bond'];
        }
    
        export const PropName = '__ComponentBond__';
        export function get(model: Model): ComponentBond | undefined {
            if (model._staticPropertyData[PropName]) return model._staticPropertyData[PropName];
            if (!model.customProperties.has(Descriptor)) return void 0;
    
            const chem_comp_bond = getChemCompBond(model);
            if (!chem_comp_bond) return void 0;
    
            const chemComp = parseChemCompBond(chem_comp_bond);
            model._staticPropertyData[PropName] = chemComp;
            return chemComp;
        }
    
        function getUniqueResidueNames(s: Structure) {
            const prop = StructureProperties.residue.label_comp_id;
            const names = new Set<string>();
            const loc = StructureElement.create();
            for (const unit of s.units) {
                if (!Unit.isAtomic(unit)) continue;
                const residues = Segmentation.transientSegments(unit.model.atomicHierarchy.residueAtomSegments, unit.elements);
                loc.unit = unit;
                while (residues.hasNext) {
                    const seg = residues.move();
                    loc.element = unit.elements[seg.start];
                    names.add(prop(loc));
                }
            }
            return names;
        }
    }