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

mol-model: refactoring Structure props

parent 15471a6a
No related branches found
No related tags found
No related merge requests found
......@@ -42,9 +42,9 @@ function copy_mmCif_category(name: keyof mmCIF_Schema): CifCategory<CifExportCon
const _entity: CifCategory<CifExportContext> = {
name: 'entity',
instance({ structures}) {
const keys = Structure.getEntityKeys(structures[0]);
return CifCategory.ofTable(structures[0].model.entities.data, keys);
instance({ structures }) {
const indices = structures[0].entityIndices;
return CifCategory.ofTable(structures[0].model.entities.data, indices);
}
}
......
......@@ -18,12 +18,13 @@ import { InterUnitBonds, computeInterUnitBonds } from './unit/links';
import { PairRestraints, CrossLinkRestraint, extractCrossLinkRestraints } from './unit/pair-restraints';
import StructureSymmetry from './symmetry';
import StructureProperties from './properties';
import { ResidueIndex, ChainIndex } from '../model/indexing';
import { ResidueIndex, ChainIndex, EntityIndex } from '../model/indexing';
import { Carbohydrates } from './carbohydrates/data';
import { computeCarbohydrates } from './carbohydrates/compute';
import { Vec3 } from 'mol-math/linear-algebra';
import { idFactory } from 'mol-util/id-factory';
import { GridLookup3D } from 'mol-math/geometry';
import { UUID } from 'mol-util';
class Structure {
/** Maps unit.id to unit */
......@@ -39,6 +40,9 @@ class Structure {
carbohydrates?: Carbohydrates,
models?: ReadonlyArray<Model>,
model?: Model,
uniqueResidueNames?: Set<string>,
entityIndices?: ReadonlyArray<EntityIndex>,
uniqueAtomicResidueIndices?: ReadonlyMap<UUID, ReadonlyArray<ResidueIndex>>,
hashCode: number,
elementCount: number,
polymerResidueCount: number,
......@@ -129,6 +133,20 @@ class Structure {
return this._props.models;
}
get uniqueResidueName() {
return this._props.uniqueResidueNames
|| (this._props.uniqueResidueNames = getUniqueResidueNames(this));
}
get entityIndices() {
return this._props.entityIndices || (this._props.entityIndices = getEntityIndices(this));
}
get uniqueAtomicResidueIndices() {
return this._props.uniqueAtomicResidueIndices
|| (this._props.uniqueAtomicResidueIndices = getUniqueAtomicResidueIndices(this));
}
/** If the structure is based on a single model, return it. Otherwise throw an exception. */
get model(): Model {
if (this._props.model) return this._props.model;
......@@ -176,6 +194,81 @@ function getModels(s: Structure) {
return arr.array;
}
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) {
// TODO: support coarse unit?
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;
}
function getEntityIndices(structure: Structure): ReadonlyArray<EntityIndex> {
const { units } = structure;
const l = StructureElement.create();
const keys = UniqueArray.create<number, EntityIndex>();
for (const unit of units) {
const prop = unit.kind === Unit.Kind.Atomic ? StructureProperties.entity.key : StructureProperties.coarse.entityKey;
l.unit = unit;
const elements = unit.elements;
const chainsIt = Segmentation.transientSegments(unit.model.atomicHierarchy.chainAtomSegments, elements);
while (chainsIt.hasNext) {
const chainSegment = chainsIt.move();
l.element = elements[chainSegment.start];
const key = prop(l);
UniqueArray.add(keys, key, key);
}
}
sortArray(keys.array);
return keys.array;
}
function getUniqueAtomicResidueIndices(structure: Structure): ReadonlyMap<UUID, ReadonlyArray<ResidueIndex>> {
const map = new Map<UUID, UniqueArray<ResidueIndex, ResidueIndex>>();
const modelIds: UUID[] = [];
const unitGroups = structure.unitSymmetryGroups;
for (const unitGroup of unitGroups) {
const unit = unitGroup.units[0];
if (!Unit.isAtomic(unit)) continue;
let uniqueResidues: UniqueArray<ResidueIndex, ResidueIndex>;
if (map.has(unit.model.id)) uniqueResidues = map.get(unit.model.id)!;
else {
uniqueResidues = UniqueArray.create<ResidueIndex, ResidueIndex>();
modelIds.push(unit.model.id);
map.set(unit.model.id, uniqueResidues);
}
const residues = Segmentation.transientSegments(unit.model.atomicHierarchy.residueAtomSegments, unit.elements);
while (residues.hasNext) {
const seg = residues.move();
UniqueArray.add(uniqueResidues, seg.index, seg.index);
}
}
const ret = new Map<UUID, ReadonlyArray<ResidueIndex>>();
for (const id of modelIds) {
const array = map.get(id)!.array;
sortArray(array);
ret.set(id, array)
}
return ret;
}
namespace Structure {
export const Empty = new Structure([]);
......@@ -346,49 +439,6 @@ namespace Structure {
}
}
export function getEntityKeys(structure: Structure) {
const { units } = structure;
const l = StructureElement.create();
const keys = UniqueArray.create<number, number>();
for (const unit of units) {
const prop = unit.kind === Unit.Kind.Atomic ? StructureProperties.entity.key : StructureProperties.coarse.entityKey;
l.unit = unit;
const elements = unit.elements;
const chainsIt = Segmentation.transientSegments(unit.model.atomicHierarchy.chainAtomSegments, elements);
while (chainsIt.hasNext) {
const chainSegment = chainsIt.move();
l.element = elements[chainSegment.start];
const key = prop(l);
UniqueArray.add(keys, key, key);
}
}
sortArray(keys.array);
return keys.array;
}
export function getUniqueAtomicResidueIndices(structure: Structure, model: Model): ReadonlyArray<ResidueIndex> {
const uniqueResidues = UniqueArray.create<ResidueIndex, ResidueIndex>();
const unitGroups = structure.unitSymmetryGroups;
for (const unitGroup of unitGroups) {
const unit = unitGroup.units[0];
if (unit.model !== model || !Unit.isAtomic(unit)) {
continue;
}
const residues = Segmentation.transientSegments(unit.model.atomicHierarchy.residueAtomSegments, unit.elements);
while (residues.hasNext) {
const seg = residues.move();
UniqueArray.add(uniqueResidues, seg.index, seg.index);
}
}
sortArray(uniqueResidues.array);
return uniqueResidues.array;
}
const distVec = Vec3.zero();
function unitElementMinDistance(unit: Unit, p: Vec3, eRadius: number) {
const { elements, conformation: { position, r } } = unit, dV = distVec;
......
......@@ -51,8 +51,8 @@ const config = {
* Paths (relative to the root directory of the model server) to JavaScript files that specify custom properties
*/
customPropertyProviders: [
'./properties/pdbe',
'./properties/rcsb'
// './properties/pdbe',
// './properties/rcsb'
],
/**
......@@ -66,9 +66,9 @@ const config = {
mapFile(source: string, id: string) {
switch (source.toLowerCase()) {
// case 'pdb': return `e:/test/quick/${id}_updated.cif`;
case 'pdb': return `e:/test/mol-star/model/out/${id}_updated.bcif`;
case 'pdb-bcif': return `e:/test/mol-star/model/out/${id}_updated.bcif`;
case 'pdb-cif': return `e:/test/mol-star/model/out/${id}_updated.cif`;
case 'pdb': return `c:/test/mol-star/model/out/${id}_updated.bcif`;
case 'pdb-bcif': return `c:/test/mol-star/model/out/${id}_updated.bcif`;
case 'pdb-cif': return `c:/test/mol-star/model/out/${id}_updated.cif`;
default: return void 0;
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment