Procházet zdrojové kódy

mol-model: custom Structure level properties (works similar way a Model properties)

David Sehnal před 6 roky
rodič
revize
cdfd1992ed

+ 33 - 20
src/mol-model/structure/export/mmcif.ts

@@ -100,8 +100,32 @@ export const mmCIF_Export_Filters = {
     }
 }
 
+function encodeCustomProp(customProp: CustomPropertyDescriptor, ctx: CifExportContext, encoder: CifWriter.Encoder, params: encode_mmCIF_categories_Params) {
+    if (!customProp.cifExport || customProp.cifExport.categories.length === 0) return;
+
+    const prefix = customProp.cifExport.prefix;
+    const cats = customProp.cifExport.categories;
+
+    let propCtx = ctx;
+    if (customProp.cifExport.context) {
+        const propId = CustomPropertyDescriptor.getUUID(customProp);
+        if (ctx.cache[propId + '__ctx']) propCtx = ctx.cache[propId + '__ctx'];
+        else {
+            propCtx = customProp.cifExport.context(ctx) || ctx;
+            ctx.cache[propId + '__ctx'] = propCtx;
+        }
+    }
+    for (const cat of cats) {
+        if (params.skipCategoryNames && params.skipCategoryNames.has(cat.name)) continue;
+        if (cat.name.indexOf(prefix) !== 0) throw new Error(`Custom category '${cat.name}' name must start with prefix '${prefix}.'`);
+        encoder.writeCategory(cat, propCtx);
+    }
+}
+
+type encode_mmCIF_categories_Params = { skipCategoryNames?: Set<string>, exportCtx?: CifExportContext }
+
 /** Doesn't start a data block */
-export function encode_mmCIF_categories(encoder: CifWriter.Encoder, structures: Structure | Structure[], params?: { skipCategoryNames?: Set<string>, exportCtx?: CifExportContext }) {
+export function encode_mmCIF_categories(encoder: CifWriter.Encoder, structures: Structure | Structure[], params?: encode_mmCIF_categories_Params) {
     const first = Array.isArray(structures) ? structures[0] : (structures as Structure);
     const models = first.models;
     if (models.length !== 1) throw 'Can\'t export stucture composed from multiple models.';
@@ -115,26 +139,15 @@ export function encode_mmCIF_categories(encoder: CifWriter.Encoder, structures:
     }
 
     for (const customProp of models[0].customProperties.all) {
-        if (!customProp.cifExport || customProp.cifExport.categories.length === 0) continue;
-
-        const prefix = customProp.cifExport.prefix;
-        const cats = customProp.cifExport.categories;
-
-        let propCtx = ctx;
-        if (customProp.cifExport.context) {
-            const propId = CustomPropertyDescriptor.getUUID(customProp);
-            if (ctx.cache[propId + '__ctx']) propCtx = ctx.cache[propId + '__ctx'];
-            else {
-                propCtx = customProp.cifExport.context(ctx) || ctx;
-                ctx.cache[propId + '__ctx'] = propCtx;
-            }
-        }
-        for (const cat of cats) {
-            if (_params.skipCategoryNames && _params.skipCategoryNames.has(cat.name)) continue;
-            if (cat.name.indexOf(prefix) !== 0) throw new Error(`Custom category '${cat.name}' name must start with prefix '${prefix}.'`);
-            encoder.writeCategory(cat, propCtx);
-        }
+        encodeCustomProp(customProp, ctx, encoder, _params);
+    }
+
+    const structureCustomProps = new Set<CustomPropertyDescriptor>();
+    for (const s of ctx.structures) {
+        if (!s.hasCustomProperties) continue;
+        for (const p of s.customPropertyDescriptors.all) structureCustomProps.add(p);
     }
+    structureCustomProps.forEach(customProp => encodeCustomProp(customProp, ctx, encoder, _params));
 }
 
 function to_mmCIF(name: string, structure: Structure, asBinary = false) {

+ 28 - 1
src/mol-model/structure/structure/structure.ts

@@ -26,6 +26,7 @@ import { Vec3, Mat4 } from 'mol-math/linear-algebra';
 import { idFactory } from 'mol-util/id-factory';
 import { GridLookup3D } from 'mol-math/geometry';
 import { UUID } from 'mol-util';
+import { CustomProperties } from '../common/custom-property';
 
 class Structure {
     /** Maps unit.id to unit */
@@ -50,7 +51,9 @@ class Structure {
         transformHash: number,
         elementCount: number,
         polymerResidueCount: number,
-        coordinateSystem: SymmetryOperator
+        coordinateSystem: SymmetryOperator,
+        propertyData?: any,
+        customProps?: CustomProperties
     } = {
         hashCode: -1,
         transformHash: -1,
@@ -68,6 +71,30 @@ class Structure {
         return this._props.elementCount;
     }
 
+    get hasCustomProperties() {
+        return !!this._props.customProps && this._props.customProps.all.length > 0;
+    }
+
+    get customPropertyDescriptors() {
+        if (!this._props.customProps) this._props.customProps = new CustomProperties();
+        return this._props.customProps;
+    }
+
+    /**
+     * Property data unique to this instance of the structure.
+     */
+    get currentPropertyData() {
+        if (!this._props.propertyData) this._props.propertyData = Object.create(null);
+        return this._props.propertyData;
+    }
+
+    /**
+     * Property data of the parent structure if it exists, currentPropertyData otherwise.
+     */
+    get inheritedPropertyData() {
+        return this.parent ? this.parent.currentPropertyData : this.currentPropertyData;
+    }
+
     /** Count of all polymer residues in the structure */
     get polymerResidueCount() {
         return this._props.polymerResidueCount;