Skip to content
Snippets Groups Projects
Commit 789a3273 authored by Alexander Rose's avatar Alexander Rose
Browse files

improved large chain partitioning

parent b8d20215
No related branches found
No related tags found
No related merge requests found
...@@ -27,6 +27,7 @@ import { idFactory } from '../../../mol-util/id-factory'; ...@@ -27,6 +27,7 @@ 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'; import { CustomProperties } from '../common/custom-property';
import { AtomicHierarchy } from '../model/properties/atomic';
class Structure { class Structure {
/** Maps unit.id to unit */ /** Maps unit.id to unit */
...@@ -379,26 +380,32 @@ namespace Structure { ...@@ -379,26 +380,32 @@ namespace Structure {
const chains = model.atomicHierarchy.chainAtomSegments; const chains = model.atomicHierarchy.chainAtomSegments;
const builder = new StructureBuilder(void 0, void 0); const builder = new StructureBuilder(void 0, void 0);
for (let c = 0; c < chains.count; c++) { for (let c = 0 as ChainIndex; c < chains.count; c++) {
const start = chains.offsets[c]; const start = chains.offsets[c];
// set to true for chains that consist of "single atom residues",
// note that it assumes there are no "zero atom residues"
let singleAtomResidues = AtomicHierarchy.chainResidueCount(model.atomicHierarchy, c) === chains.offsets[c + 1] - chains.offsets[c]
// merge all consecutive "single atom chains" with same entity id // merge all consecutive "single atom chains" with same entity id
while (c + 1 < chains.count while (c + 1 < chains.count
&& chains.offsets[c + 1] - chains.offsets[c] === 1 && chains.offsets[c + 1] - chains.offsets[c] === 1
&& chains.offsets[c + 2] - chains.offsets[c + 1] === 1 && chains.offsets[c + 2] - chains.offsets[c + 1] === 1
) { ) {
c++; c++;
const e1 = model.atomicHierarchy.index.getEntityFromChain(c as ChainIndex); singleAtomResidues = true
const e1 = model.atomicHierarchy.index.getEntityFromChain(c);
const e2 = model.atomicHierarchy.index.getEntityFromChain(c + 1 as ChainIndex); const e2 = model.atomicHierarchy.index.getEntityFromChain(c + 1 as ChainIndex);
if (e1 !== e2) break if (e1 !== e2) break
} }
const elements = SortedArray.ofBounds(start as ElementIndex, chains.offsets[c + 1] as ElementIndex); const elements = SortedArray.ofBounds(start as ElementIndex, chains.offsets[c + 1] as ElementIndex);
if (isWaterChain(model, c as ChainIndex)) { if (singleAtomResidues) {
partitionAtomicUnit(model, elements, builder); partitionAtomicUnitByAtom(model, elements, builder);
} else if (elements.length > 200000) { } else if (elements.length > 200000 || isWaterChain(model, c)) {
partitionAtomicUnitPerResidue(model, elements, builder); // split up very large chains e.g. lipid bilayers, micelles or water with explicit H
partitionAtomicUnitByResidue(model, elements, builder);
} else { } else {
builder.addUnit(Unit.Kind.Atomic, model, SymmetryOperator.Default, elements); builder.addUnit(Unit.Kind.Atomic, model, SymmetryOperator.Default, elements);
} }
...@@ -422,9 +429,9 @@ namespace Structure { ...@@ -422,9 +429,9 @@ namespace Structure {
return model.entities.data.type.value(e) === 'water'; return model.entities.data.type.value(e) === 'water';
} }
function partitionAtomicUnit(model: Model, indices: SortedArray, builder: StructureBuilder) { function partitionAtomicUnitByAtom(model: Model, indices: SortedArray, builder: StructureBuilder) {
const { x, y, z } = model.atomicConformation; const { x, y, z } = model.atomicConformation;
const lookup = GridLookup3D({ x, y, z, indices }, Vec3.create(64, 64, 64)); const lookup = GridLookup3D({ x, y, z, indices }, 8192);
const { offset, count, array } = lookup.buckets; const { offset, count, array } = lookup.buckets;
for (let i = 0, _i = offset.length; i < _i; i++) { for (let i = 0, _i = offset.length; i < _i; i++) {
...@@ -437,7 +444,8 @@ namespace Structure { ...@@ -437,7 +444,8 @@ namespace Structure {
} }
} }
function partitionAtomicUnitPerResidue(model: Model, indices: SortedArray, builder: StructureBuilder) { // keeps atoms of residues together
function partitionAtomicUnitByResidue(model: Model, indices: SortedArray, builder: StructureBuilder) {
model.atomicHierarchy.residueAtomSegments.offsets model.atomicHierarchy.residueAtomSegments.offsets
const startIndices: number[] = [] const startIndices: number[] = []
...@@ -446,12 +454,12 @@ namespace Structure { ...@@ -446,12 +454,12 @@ namespace Structure {
const residueIt = Segmentation.transientSegments(model.atomicHierarchy.residueAtomSegments, indices) const residueIt = Segmentation.transientSegments(model.atomicHierarchy.residueAtomSegments, indices)
while (residueIt.hasNext) { while (residueIt.hasNext) {
const residueSegment = residueIt.move(); const residueSegment = residueIt.move();
startIndices[startIndices.length] = residueSegment.start startIndices[startIndices.length] = indices[residueSegment.start]
endIndices[endIndices.length] = residueSegment.end endIndices[endIndices.length] = indices[residueSegment.end]
} }
const { x, y, z } = model.atomicConformation; const { x, y, z } = model.atomicConformation;
const lookup = GridLookup3D({ x, y, z, indices: SortedArray.ofSortedArray(startIndices) }, Vec3.create(256, 256, 256)); const lookup = GridLookup3D({ x, y, z, indices: SortedArray.ofSortedArray(startIndices) }, 8192);
const { offset, count, array } = lookup.buckets; const { offset, count, array } = lookup.buckets;
for (let i = 0, _i = offset.length; i < _i; i++) { for (let i = 0, _i = offset.length; i < _i; i++) {
...@@ -463,7 +471,7 @@ namespace Structure { ...@@ -463,7 +471,7 @@ namespace Structure {
set[set.length] = l; set[set.length] = l;
} }
} }
builder.addUnit(Unit.Kind.Atomic, model, SymmetryOperator.Default, SortedArray.ofSortedArray(set)); builder.addUnit(Unit.Kind.Atomic, model, SymmetryOperator.Default, SortedArray.ofSortedArray(new Int32Array(set)));
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment