molstar
Version:
A comprehensive macromolecular library.
185 lines (184 loc) • 7.67 kB
JavaScript
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { StructureElement } from '../../../structure';
import { Segmentation } from '../../../../../mol-data/int';
import { UUID } from '../../../../../mol-util';
export var IndexedCustomProperty;
(function (IndexedCustomProperty) {
function getCifDataSource(structure, prop, cache) {
if (!prop)
return { rowCount: 0 };
if (cache && cache[prop.id])
return cache[prop.id];
const data = prop.getElements(structure);
const ret = { data, rowCount: data.elements.length };
if (cache)
cache[prop.id] = ret;
return ret;
}
IndexedCustomProperty.getCifDataSource = getCifDataSource;
function fromAtomMap(map) {
return new ElementMappedCustomProperty(map);
}
IndexedCustomProperty.fromAtomMap = fromAtomMap;
function fromAtomArray(array) {
// TODO: create "array based custom property" as optimization
return new ElementMappedCustomProperty(arrayToMap(array));
}
IndexedCustomProperty.fromAtomArray = fromAtomArray;
const getResidueSegments = (model) => model.atomicHierarchy.residueAtomSegments;
function fromResidueMap(map) {
return new SegmentedMappedIndexedCustomProperty('residue', map, getResidueSegments, 0 /* Unit.Kind.Atomic */);
}
IndexedCustomProperty.fromResidueMap = fromResidueMap;
function fromResidueArray(array) {
// TODO: create "array based custom property" as optimization
return new SegmentedMappedIndexedCustomProperty('residue', arrayToMap(array), getResidueSegments, 0 /* Unit.Kind.Atomic */);
}
IndexedCustomProperty.fromResidueArray = fromResidueArray;
const getChainSegments = (model) => model.atomicHierarchy.chainAtomSegments;
function fromChainMap(map) {
return new SegmentedMappedIndexedCustomProperty('chain', map, getChainSegments, 0 /* Unit.Kind.Atomic */);
}
IndexedCustomProperty.fromChainMap = fromChainMap;
function fromChainArray(array) {
// TODO: create "array based custom property" as optimization
return new SegmentedMappedIndexedCustomProperty('chain', arrayToMap(array), getChainSegments, 0 /* Unit.Kind.Atomic */);
}
IndexedCustomProperty.fromChainArray = fromChainArray;
function fromEntityMap(map) {
return new EntityMappedCustomProperty(map);
}
IndexedCustomProperty.fromEntityMap = fromEntityMap;
})(IndexedCustomProperty || (IndexedCustomProperty = {}));
function arrayToMap(array) {
const ret = new Map();
for (let i = 0, _i = array.length; i < _i; i++)
ret.set(i, array[i]);
return ret;
}
class SegmentedMappedIndexedCustomProperty {
has(idx) { return this.map.has(idx); }
get(idx) { return this.map.get(idx); }
getStructureElements(structure) {
const models = structure.models;
if (models.length !== 1)
throw new Error(`Only works on structures with a single model.`);
const seenIndices = new Set();
const unitGroups = structure.unitSymmetryGroups;
const loci = [];
const segments = this.segmentGetter(models[0]);
for (const unitGroup of unitGroups) {
const unit = unitGroup.units[0];
if (unit.kind !== this.kind) {
continue;
}
const chains = Segmentation.transientSegments(segments, unit.elements);
while (chains.hasNext) {
const seg = chains.move();
if (!this.has(seg.index) || seenIndices.has(seg.index))
continue;
seenIndices.add(seg.index);
loci[loci.length] = StructureElement.Location.create(structure, unit, unit.elements[seg.start]);
}
}
loci.sort((x, y) => x.element - y.element);
return loci;
}
getElements(structure) {
const index = this.segmentGetter(structure.model).index;
const elements = this.getStructureElements(structure);
return { elements, property: i => this.get(index[elements[i].element]) };
}
constructor(level, map, segmentGetter, kind) {
this.level = level;
this.map = map;
this.segmentGetter = segmentGetter;
this.id = UUID.create22();
this.kind = kind;
}
}
class ElementMappedCustomProperty {
has(idx) { return this.map.has(idx); }
get(idx) { return this.map.get(idx); }
getStructureElements(structure) {
const models = structure.models;
if (models.length !== 1)
throw new Error(`Only works on structures with a single model.`);
const seenIndices = new Set();
const unitGroups = structure.unitSymmetryGroups;
const loci = [];
for (const unitGroup of unitGroups) {
const unit = unitGroup.units[0];
if (unit.kind !== this.kind) {
continue;
}
const elements = unit.elements;
for (let i = 0, _i = elements.length; i < _i; i++) {
const e = elements[i];
if (!this.has(e) || seenIndices.has(e))
continue;
seenIndices.add(elements[i]);
loci[loci.length] = StructureElement.Location.create(structure, unit, e);
}
}
loci.sort((x, y) => x.element - y.element);
return loci;
}
getElements(structure) {
const elements = this.getStructureElements(structure);
return { elements, property: i => this.get(elements[i].element) };
}
constructor(map) {
this.map = map;
this.id = UUID.create22();
this.level = 'atom';
this.kind = 0 /* Unit.Kind.Atomic */;
}
}
class EntityMappedCustomProperty {
has(idx) { return this.map.has(idx); }
get(idx) { return this.map.get(idx); }
getStructureElements(structure) {
const models = structure.models;
if (models.length !== 1)
throw new Error(`Only works on structures with a single model.`);
const index = models[0].atomicHierarchy.index;
const seenIndices = new Set();
const unitGroups = structure.unitSymmetryGroups;
const loci = [];
const segments = models[0].atomicHierarchy.chainAtomSegments;
for (const unitGroup of unitGroups) {
const unit = unitGroup.units[0];
if (unit.kind !== this.kind) {
continue;
}
const chains = Segmentation.transientSegments(segments, unit.elements);
while (chains.hasNext) {
const seg = chains.move();
const eI = index.getEntityFromChain(seg.index);
if (!this.has(eI) || seenIndices.has(eI))
continue;
seenIndices.add(eI);
loci[loci.length] = StructureElement.Location.create(structure, unit, unit.elements[seg.start]);
}
}
loci.sort((x, y) => x.element - y.element);
return loci;
}
getElements(structure) {
const elements = this.getStructureElements(structure);
const chainIndex = structure.model.atomicHierarchy.chainAtomSegments.index;
const index = structure.model.atomicHierarchy.index;
return { elements, property: i => this.get(index.getEntityFromChain(chainIndex[elements[i].element])) };
}
constructor(map) {
this.map = map;
this.id = UUID.create22();
this.level = 'entity';
this.kind = 0 /* Unit.Kind.Atomic */;
}
}