|
@@ -7,12 +7,50 @@
|
|
|
|
|
|
import Model from '../../../model'
|
|
|
import { LinkType } from '../../../types'
|
|
|
+import { ModelPropertyDescriptor } from '../../../properties/custom';
|
|
|
+import { mmCIF_Database } from 'mol-io/reader/cif/schema/mmcif';
|
|
|
+import { Structure, Unit, StructureProperties, Element } from '../../../../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: {
|
|
|
+ categoryNames: ['chem_comp_bond'],
|
|
|
+ categoryProvider(ctx) {
|
|
|
+ const comp_names = getUniqueResidueNames(ctx.structure);
|
|
|
+ const chem_comp_bond = getChemCompBond(ctx.model);
|
|
|
+
|
|
|
+ if (!chem_comp_bond) return [];
|
|
|
+
|
|
|
+ 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', chem_comp_bond, indices)
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ export function attachFromMmCif(model: Model): boolean {
|
|
|
+ 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 class ComponentBondImpl implements ComponentBond {
|
|
|
entries: Map<string, ComponentBond.Entry> = new Map();
|
|
|
|
|
@@ -46,13 +84,15 @@ export namespace ComponentBond {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ function getChemCompBond(model: Model) {
|
|
|
+ return model._staticPropertyData.__ComponentBondData__ as mmCIF_Database['chem_comp_bond'];
|
|
|
+ }
|
|
|
+
|
|
|
export const PropName = '__ComponentBond__';
|
|
|
- export function fromModel(model: Model): ComponentBond | undefined {
|
|
|
+ export function get(model: Model): ComponentBond | undefined {
|
|
|
if (model._staticPropertyData[PropName]) return model._staticPropertyData[PropName];
|
|
|
-
|
|
|
- if (model.sourceData.kind !== 'mmCIF') return
|
|
|
- const { chem_comp_bond } = model.sourceData.data;
|
|
|
- if (!chem_comp_bond._rowCount) return void 0;
|
|
|
+ if (!model.customProperties.has(Descriptor)) return void 0;
|
|
|
+ const chem_comp_bond = getChemCompBond(model);
|
|
|
|
|
|
let compBond = new ComponentBondImpl();
|
|
|
|
|
@@ -90,4 +130,21 @@ export namespace ComponentBond {
|
|
|
model._staticPropertyData[PropName] = compBond;
|
|
|
return compBond;
|
|
|
}
|
|
|
+
|
|
|
+ function getUniqueResidueNames(s: Structure) {
|
|
|
+ const prop = StructureProperties.residue.label_comp_id;
|
|
|
+ const names = new Set<string>();
|
|
|
+ const loc = Element.Location();
|
|
|
+ for (const unit of s.units) {
|
|
|
+ if (!Unit.isAtomic(unit)) continue;
|
|
|
+ const residues = Segmentation.transientSegments(unit.model.atomicHierarchy.residueSegments, unit.elements);
|
|
|
+ loc.unit = unit;
|
|
|
+ while (residues.hasNext) {
|
|
|
+ const seg = residues.move();
|
|
|
+ loc.element = seg.start;
|
|
|
+ names.add(prop(loc));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return names;
|
|
|
+ }
|
|
|
}
|