molstar
Version:
A comprehensive macromolecular library.
130 lines (129 loc) • 4.14 kB
JavaScript
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Structure } from '../../structure';
import { SortedArray } from '../../../../mol-data/int';
export function structureUnion(source, structures) {
if (structures.length === 0)
return Structure.Empty;
if (structures.length === 1)
return structures[0];
var unitMap = new Map();
var fullUnits = new Set();
for (var _a = 0, structures_1 = structures; _a < structures_1.length; _a++) {
var units = structures_1[_a].units;
for (var i = 0, _i = units.length; i < _i; i++) {
var u = units[i];
if (unitMap.has(u.id)) {
// check if there is anything more to union in this particual unit.
if (fullUnits.has(u.id))
continue;
var merged = SortedArray.union(unitMap.get(u.id), u.elements);
unitMap.set(u.id, merged);
if (merged.length === source.unitMap.get(u.id).elements.length)
fullUnits.add(u.id);
}
else {
unitMap.set(u.id, u.elements);
if (u.elements.length === source.unitMap.get(u.id).elements.length)
fullUnits.add(u.id);
}
}
}
var builder = source.subsetBuilder(true);
unitMap.forEach(buildUnion, builder);
return builder.getStructure();
}
function buildUnion(elements, id) {
this.setUnit(id, elements);
}
export function structureAreEqual(sA, sB) {
if (sA === sB)
return true;
if (sA.units.length !== sB.units.length)
return false;
var aU = sA.units, bU = sB.unitMap;
for (var i = 0, _i = aU.length; i < _i; i++) {
var u = aU[i];
if (!bU.has(u.id))
return false;
var v = bU.get(u.id);
if (!SortedArray.areEqual(u.elements, v.elements))
return false;
}
return true;
}
export function structureAreIntersecting(sA, sB) {
if (sA === sB)
return true;
var a, b;
if (sA.units.length < sB.units.length) {
a = sA;
b = sB;
}
else {
a = sB;
b = sA;
}
var aU = a.units, bU = b.unitMap;
for (var i = 0, _i = aU.length; i < _i; i++) {
var u = aU[i];
if (!bU.has(u.id))
continue;
var v = bU.get(u.id);
if (SortedArray.areIntersecting(u.elements, v.elements))
return true;
}
return false;
}
export function structureIntersect(sA, sB) {
if (sA === sB)
return sA;
if (!structureAreIntersecting(sA, sB))
return Structure.Empty;
var a, b;
if (sA.units.length < sB.units.length) {
a = sA;
b = sB;
}
else {
a = sB;
b = sA;
}
var aU = a.units, bU = b.unitMap;
var units = [];
for (var i = 0, _i = aU.length; i < _i; i++) {
var u = aU[i];
if (!bU.has(u.id))
continue;
var v = bU.get(u.id);
if (SortedArray.areIntersecting(u.elements, v.elements)) {
var int = SortedArray.intersect(u.elements, v.elements);
units[units.length] = u.getChild(int);
}
}
return Structure.create(units, { parent: sA.parent || sB.parent });
}
export function structureSubtract(a, b) {
if (a === b)
return Structure.Empty;
if (!structureAreIntersecting(a, b))
return a;
var aU = a.units, bU = b.unitMap;
var units = [];
for (var i = 0, _i = aU.length; i < _i; i++) {
var u = aU[i];
if (!bU.has(u.id)) {
units[units.length] = u;
continue;
}
var v = bU.get(u.id);
var sub = SortedArray.subtract(u.elements, v.elements);
if (sub.length > 0) {
units[units.length] = u.getChild(sub);
}
}
return Structure.create(units, { parent: a.parent || b.parent });
}