molstar
Version:
A comprehensive macromolecular library.
100 lines • 4.05 kB
JavaScript
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { OrderedSet } from '../ordered-set';
import { Interval } from '../interval';
import { SortedArray } from '../sorted-array';
export function create(values) {
var offsets = SortedArray.ofSortedArray(values);
var max = SortedArray.max(offsets);
var index = new Int32Array(max);
for (var i = 0, _i = values.length - 1; i < _i; i++) {
for (var j = values[i], _j = values[i + 1]; j < _j; j++) {
index[j] = i;
}
}
return { offsets: offsets, index: index, count: values.length - 1 };
}
export function ofOffsets(offsets, bounds) {
var s = Interval.start(bounds);
var segments = new Int32Array(offsets.length + 1);
for (var i = 0, _i = offsets.length; i < _i; i++) {
segments[i] = offsets[i] - s;
}
segments[offsets.length] = Interval.end(bounds) - s;
return create(segments);
}
/** Get number of segments in a segmentation */
export function count(_a) {
var count = _a.count;
return count;
}
export function getSegment(_a, value) {
var index = _a.index;
return index[value];
}
export function projectValue(_a, set, value) {
var offsets = _a.offsets;
var last = OrderedSet.max(offsets);
var idx = value >= last ? -1 : OrderedSet.findPredecessorIndex(offsets, value - 1);
return OrderedSet.findRange(set, OrderedSet.getAt(offsets, idx), OrderedSet.getAt(offsets, idx + 1) - 1);
}
var SegmentIterator = /** @class */ (function () {
function SegmentIterator(segments, segmentMap, set, inputRange) {
this.segments = segments;
this.segmentMap = segmentMap;
this.set = set;
this.segmentMin = 0;
this.segmentMax = 0;
this.setRange = Interval.Empty;
this.value = { index: 0, start: 0, end: 0 };
this.hasNext = false;
this.setRange = inputRange;
this.updateSegmentRange();
}
SegmentIterator.prototype.move = function () {
while (this.hasNext) {
if (this.updateValue()) {
this.value.index = this.segmentMin++;
this.hasNext = this.segmentMax >= this.segmentMin && Interval.size(this.setRange) > 0;
break;
}
else {
this.updateSegmentRange();
}
}
return this.value;
};
SegmentIterator.prototype.updateValue = function () {
var segmentEnd = this.segments[this.segmentMin + 1];
// TODO: add optimized version for interval and array?
var setEnd = OrderedSet.findPredecessorIndexInInterval(this.set, segmentEnd, this.setRange);
this.value.start = Interval.start(this.setRange);
this.value.end = setEnd;
this.setRange = Interval.ofBounds(setEnd, Interval.end(this.setRange));
return setEnd > this.value.start;
};
SegmentIterator.prototype.updateSegmentRange = function () {
var sMin = Interval.min(this.setRange), sMax = Interval.max(this.setRange);
if (sMax < sMin) {
this.hasNext = false;
return;
}
this.segmentMin = this.segmentMap[OrderedSet.getAt(this.set, sMin)];
this.segmentMax = this.segmentMap[OrderedSet.getAt(this.set, sMax)];
this.hasNext = this.segmentMax >= this.segmentMin;
};
SegmentIterator.prototype.setSegment = function (segment) {
this.setRange = Interval.ofBounds(segment.start, segment.end);
this.updateSegmentRange();
};
return SegmentIterator;
}());
export { SegmentIterator };
export function segments(segs, set, segment) {
var int = typeof segment !== 'undefined' ? Interval.ofBounds(segment.start, segment.end) : Interval.ofBounds(0, OrderedSet.size(set));
return new SegmentIterator(segs.offsets, segs.index, set, int);
}
//# sourceMappingURL=segmentation.js.map