Skip to content
Snippets Groups Projects
Commit cdfd1992 authored by David Sehnal's avatar David Sehnal
Browse files

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

parent a85a4b09
No related branches found
No related tags found
No related merge requests found
...@@ -100,8 +100,32 @@ export const mmCIF_Export_Filters = { ...@@ -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 */ /** 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 first = Array.isArray(structures) ? structures[0] : (structures as Structure);
const models = first.models; const models = first.models;
if (models.length !== 1) throw 'Can\'t export stucture composed from multiple 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: ...@@ -115,26 +139,15 @@ export function encode_mmCIF_categories(encoder: CifWriter.Encoder, structures:
} }
for (const customProp of models[0].customProperties.all) { for (const customProp of models[0].customProperties.all) {
if (!customProp.cifExport || customProp.cifExport.categories.length === 0) continue; encodeCustomProp(customProp, ctx, encoder, _params);
}
const prefix = customProp.cifExport.prefix;
const cats = customProp.cifExport.categories; const structureCustomProps = new Set<CustomPropertyDescriptor>();
for (const s of ctx.structures) {
let propCtx = ctx; if (!s.hasCustomProperties) continue;
if (customProp.cifExport.context) { for (const p of s.customPropertyDescriptors.all) structureCustomProps.add(p);
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);
}
} }
structureCustomProps.forEach(customProp => encodeCustomProp(customProp, ctx, encoder, _params));
} }
function to_mmCIF(name: string, structure: Structure, asBinary = false) { function to_mmCIF(name: string, structure: Structure, asBinary = false) {
......
...@@ -26,6 +26,7 @@ import { Vec3, Mat4 } from 'mol-math/linear-algebra'; ...@@ -26,6 +26,7 @@ import { Vec3, Mat4 } from 'mol-math/linear-algebra';
import { idFactory } from 'mol-util/id-factory'; import { idFactory } from 'mol-util/id-factory';
import { GridLookup3D } from 'mol-math/geometry'; import { GridLookup3D } from 'mol-math/geometry';
import { UUID } from 'mol-util'; import { UUID } from 'mol-util';
import { CustomProperties } from '../common/custom-property';
class Structure { class Structure {
/** Maps unit.id to unit */ /** Maps unit.id to unit */
...@@ -50,7 +51,9 @@ class Structure { ...@@ -50,7 +51,9 @@ class Structure {
transformHash: number, transformHash: number,
elementCount: number, elementCount: number,
polymerResidueCount: number, polymerResidueCount: number,
coordinateSystem: SymmetryOperator coordinateSystem: SymmetryOperator,
propertyData?: any,
customProps?: CustomProperties
} = { } = {
hashCode: -1, hashCode: -1,
transformHash: -1, transformHash: -1,
...@@ -68,6 +71,30 @@ class Structure { ...@@ -68,6 +71,30 @@ class Structure {
return this._props.elementCount; 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 */ /** Count of all polymer residues in the structure */
get polymerResidueCount() { get polymerResidueCount() {
return this._props.polymerResidueCount; return this._props.polymerResidueCount;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment