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

optimized repr loci iteration, marking and extendToWholeChains

parent 1c58bca4
Branches
Tags
No related merge requests found
......@@ -282,7 +282,7 @@ namespace StructureElement {
const elements: Loci['elements'][0][] = [];
for (const lociElement of loci.elements) {
const newIndices: UnitIndex[] = [];
const _newIndices: UnitIndex[] = [];
const unitElements = lociElement.unit.elements;
const { index: chainIndex, offsets: chainOffsets } = getChainSegments(lociElement.unit)
......@@ -298,11 +298,18 @@ namespace StructureElement {
for (let j = chainOffsets[cI], _j = chainOffsets[cI + 1]; j < _j; j++) {
const idx = OrderedSet.indexOf(unitElements, j);
if (idx >= 0) newIndices[newIndices.length] = idx as UnitIndex;
if (idx >= 0) _newIndices[_newIndices.length] = idx as UnitIndex;
}
}
elements[elements.length] = { unit: lociElement.unit, indices: SortedArray.ofSortedArray(newIndices) };
let newIndices: OrderedSet<UnitIndex>
if (_newIndices.length > 12 && _newIndices[_newIndices.length - 1] - _newIndices[0] === _newIndices.length - 1) {
newIndices = Interval.ofRange(_newIndices[0], _newIndices[_newIndices.length - 1])
} else {
newIndices = SortedArray.ofSortedArray(_newIndices)
}
elements[elements.length] = { unit: lociElement.unit, indices: newIndices };
}
return Loci(loci.structure, elements);
......
......@@ -169,8 +169,10 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R
if (!Structure.areParentsEquivalent(loci.structure, _structure)) return false
if (StructureElement.isLoci(loci)) {
loci = StructureElement.Loci.remap(loci, _structure)
if (loci.elements.length === 0) return false
} else if (Link.isLoci(loci)) {
loci = Link.remapLoci(loci, _structure)
if (loci.links.length === 0) return false
}
visuals.forEach(({ visual }) => {
changed = visual.mark(loci, action) || changed
......
......@@ -41,6 +41,10 @@ export function getNucleotideElementLoci(pickingId: PickingId, structureGroup: S
return EmptyLoci
}
/**
* Mark a nucleotide element (e.g. part of a cartoon block)
* - mark only when all its residue's elements are in a loci
*/
export function eachNucleotideElement(loci: Loci, structureGroup: StructureGroup, apply: (interval: Interval) => boolean) {
let changed = false
if (!StructureElement.isLoci(loci)) return false
......@@ -56,19 +60,25 @@ export function eachNucleotideElement(loci: Loci, structureGroup: StructureGroup
const unitIdx = group.unitIndexMap.get(e.unit.id)
const eUnit = e.unit
if (unitIdx !== undefined && Unit.isAtomic(eUnit)) {
// TODO optimized implementation for intervals
OrderedSet.forEach(e.indices, v => {
const rI = index[elements[v]]
const unitIndexMin = OrderedSet.findPredecessorIndex(elements, offsets[rI])
const unitIndexMax = OrderedSet.findPredecessorIndex(elements, offsets[rI + 1] - 1)
const unitIndexInterval = Interval.ofRange(unitIndexMin, unitIndexMax)
if (!OrderedSet.isSubset(e.indices, unitIndexInterval)) return
const eI = traceElementIndex[rI]
const idx = OrderedSet.indexOf(eUnit.nucleotideElements, eI)
if (idx !== -1) {
if (apply(Interval.ofSingleton(unitIdx * groupCount + idx))) changed = true
}
})
// TODO optimized implementation for intervals covering only part of the unit
if (Interval.is(e.indices) && Interval.start(e.indices) === 0 && Interval.end(e.indices) === e.unit.elements.length) {
const start = unitIdx * groupCount;
const end = unitIdx * groupCount + groupCount;
if (apply(Interval.ofBounds(start, end))) changed = true
} else {
OrderedSet.forEach(e.indices, v => {
const rI = index[elements[v]]
const unitIndexMin = OrderedSet.findPredecessorIndex(elements, offsets[rI])
const unitIndexMax = OrderedSet.findPredecessorIndex(elements, offsets[rI + 1] - 1)
const unitIndexInterval = Interval.ofRange(unitIndexMin, unitIndexMax)
if (!OrderedSet.isSubset(e.indices, unitIndexInterval)) return
const eI = traceElementIndex[rI]
const idx = OrderedSet.indexOf(eUnit.nucleotideElements, eI)
if (idx !== -1) {
if (apply(Interval.ofSingleton(unitIdx * groupCount + idx))) changed = true
}
})
}
}
}
return changed
......
......@@ -104,19 +104,25 @@ export function eachPolymerElement(loci: Loci, structureGroup: StructureGroup, a
const unitIdx = group.unitIndexMap.get(e.unit.id)
if (unitIdx !== undefined) {
if (Unit.isAtomic(e.unit)) {
// TODO optimized implementation for intervals
OrderedSet.forEach(e.indices, v => {
const rI = index[elements[v]]
const unitIndexMin = OrderedSet.findPredecessorIndex(elements, offsets[rI])
const unitIndexMax = OrderedSet.findPredecessorIndex(elements, offsets[rI + 1] - 1)
const unitIndexInterval = Interval.ofRange(unitIndexMin, unitIndexMax)
if (!OrderedSet.isSubset(e.indices, unitIndexInterval)) return
const eI = traceElementIndex[rI]
const idx = OrderedSet.indexOf(e.unit.polymerElements, eI)
if (idx !== -1) {
if (apply(Interval.ofSingleton(unitIdx * groupCount + idx))) changed = true
}
})
// TODO optimized implementation for intervals covering only part of the unit
if (Interval.is(e.indices) && Interval.start(e.indices) === 0 && Interval.end(e.indices) === e.unit.elements.length) {
const start = unitIdx * groupCount;
const end = unitIdx * groupCount + groupCount;
if (apply(Interval.ofBounds(start, end))) changed = true
} else {
OrderedSet.forEach(e.indices, v => {
const rI = index[elements[v]]
const unitIndexMin = OrderedSet.findPredecessorIndex(elements, offsets[rI])
const unitIndexMax = OrderedSet.findPredecessorIndex(elements, offsets[rI + 1] - 1)
const unitIndexInterval = Interval.ofRange(unitIndexMin, unitIndexMax)
if (!OrderedSet.isSubset(e.indices, unitIndexInterval)) return
const eI = traceElementIndex[rI]
const idx = OrderedSet.indexOf(e.unit.polymerElements, eI)
if (idx !== -1) {
if (apply(Interval.ofSingleton(unitIdx * groupCount + idx))) changed = true
}
})
}
} else {
if (Interval.is(e.indices)) {
const start = unitIdx * groupCount + Interval.start(e.indices);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment