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

loci remapping

parent 4894b110
Branches
Tags
No related merge requests found
Showing
with 61 additions and 4 deletions
...@@ -141,10 +141,29 @@ namespace StructureElement { ...@@ -141,10 +141,29 @@ namespace StructureElement {
export function remap(loci: Loci, structure: Structure): Loci { export function remap(loci: Loci, structure: Structure): Loci {
if (structure === loci.structure) return loci if (structure === loci.structure) return loci
return Loci(structure, loci.elements.map(e => ({ const elements: Loci['elements'][0][] = [];
unit: structure.unitMap.get(e.unit.id)!, loci.elements.forEach(e => {
indices: e.indices const unit = structure.unitMap.get(e.unit.id)
}))); if (!unit) return
if (SortedArray.areEqual(e.unit.elements, unit.elements)) {
elements.push({ unit, indices: e.indices })
} else {
// TODO optimize
const indices: UnitIndex[] = []
OrderedSet.forEach(e.indices, (v) => {
const eI = e.unit.elements[v]
const uI = SortedArray.indexOf(unit.elements, eI) as UnitIndex | -1
if (uI !== -1) indices.push(uI)
})
elements.push({
unit,
indices: SortedArray.ofSortedArray(indices)
})
}
});
return Loci(structure, elements);
} }
export function union(xs: Loci, ys: Loci): Loci { export function union(xs: Loci, ys: Loci): Loci {
......
...@@ -62,6 +62,29 @@ namespace Link { ...@@ -62,6 +62,29 @@ namespace Link {
return true return true
} }
export function remapLoci(loci: Loci, structure: Structure): Loci {
if (structure === loci.structure) return loci
const links: Loci['links'][0][] = [];
loci.links.forEach(l => {
const unitA = structure.unitMap.get(l.aUnit.id)
if (!unitA) return
const unitB = structure.unitMap.get(l.bUnit.id)
if (!unitB) return
const elementA = l.aUnit.elements[l.aIndex]
const indexA = SortedArray.indexOf(unitA.elements, elementA) as StructureElement.UnitIndex | -1
if (indexA === -1) return
const elementB = l.bUnit.elements[l.bIndex]
const indexB = SortedArray.indexOf(unitB.elements, elementB) as StructureElement.UnitIndex | -1
if (indexB === -1) return
links.push(Location(unitA, indexA, unitB, indexB))
});
return Loci(structure, links);
}
export function toStructureElementLoci(loci: Loci): StructureElement.Loci { export function toStructureElementLoci(loci: Loci): StructureElement.Loci {
const elements: StructureElement.Loci['elements'][0][] = [] const elements: StructureElement.Loci['elements'][0][] = []
const map = new Map<number, number[]>() const map = new Map<number, number[]>()
......
...@@ -120,6 +120,7 @@ function eachCarbohydrateLink(loci: Loci, structure: Structure, apply: (interval ...@@ -120,6 +120,7 @@ function eachCarbohydrateLink(loci: Loci, structure: Structure, apply: (interval
let changed = false let changed = false
if (Link.isLoci(loci)) { if (Link.isLoci(loci)) {
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = Link.remapLoci(loci, structure)
const { getLinkIndex } = structure.carbohydrates const { getLinkIndex } = structure.carbohydrates
for (const l of loci.links) { for (const l of loci.links) {
const idx = getLinkIndex(l.aUnit, l.aUnit.elements[l.aIndex], l.bUnit, l.bUnit.elements[l.bIndex]) const idx = getLinkIndex(l.aUnit, l.aUnit.elements[l.aIndex], l.bUnit, l.bUnit.elements[l.bIndex])
...@@ -129,6 +130,7 @@ function eachCarbohydrateLink(loci: Loci, structure: Structure, apply: (interval ...@@ -129,6 +130,7 @@ function eachCarbohydrateLink(loci: Loci, structure: Structure, apply: (interval
} }
} else if (StructureElement.isLoci(loci)) { } else if (StructureElement.isLoci(loci)) {
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = StructureElement.Loci.remap(loci, structure)
// TODO mark link only when both of the link elements are in a StructureElement.Loci // TODO mark link only when both of the link elements are in a StructureElement.Loci
const { getElementIndex, getLinkIndices, elements } = structure.carbohydrates const { getElementIndex, getLinkIndices, elements } = structure.carbohydrates
for (const e of loci.elements) { for (const e of loci.elements) {
......
...@@ -197,6 +197,7 @@ function eachCarbohydrate(loci: Loci, structure: Structure, apply: (interval: In ...@@ -197,6 +197,7 @@ function eachCarbohydrate(loci: Loci, structure: Structure, apply: (interval: In
let changed = false let changed = false
if (!StructureElement.isLoci(loci)) return false if (!StructureElement.isLoci(loci)) return false
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = StructureElement.Loci.remap(loci, structure)
for (const e of loci.elements) { for (const e of loci.elements) {
// TODO make more efficient by handling/grouping `e.indices` by residue index // TODO make more efficient by handling/grouping `e.indices` by residue index
// TODO only call apply when the full alt-residue of the unit is part of `e` // TODO only call apply when the full alt-residue of the unit is part of `e`
......
...@@ -134,6 +134,7 @@ function eachTerminalLink(loci: Loci, structure: Structure, apply: (interval: In ...@@ -134,6 +134,7 @@ function eachTerminalLink(loci: Loci, structure: Structure, apply: (interval: In
let changed = false let changed = false
if (Link.isLoci(loci)) { if (Link.isLoci(loci)) {
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = Link.remapLoci(loci, structure)
for (const l of loci.links) { for (const l of loci.links) {
const idx = getTerminalLinkIndex(l.aUnit, l.aUnit.elements[l.aIndex], l.bUnit, l.bUnit.elements[l.bIndex]) const idx = getTerminalLinkIndex(l.aUnit, l.aUnit.elements[l.aIndex], l.bUnit, l.bUnit.elements[l.bIndex])
if (idx !== undefined) { if (idx !== undefined) {
...@@ -142,6 +143,7 @@ function eachTerminalLink(loci: Loci, structure: Structure, apply: (interval: In ...@@ -142,6 +143,7 @@ function eachTerminalLink(loci: Loci, structure: Structure, apply: (interval: In
} }
} else if (StructureElement.isLoci(loci)) { } else if (StructureElement.isLoci(loci)) {
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = StructureElement.Loci.remap(loci, structure)
// TODO mark link only when both of the link elements are in a StructureElement.Loci // TODO mark link only when both of the link elements are in a StructureElement.Loci
const { getElementIndex, getTerminalLinkIndices, elements } = structure.carbohydrates const { getElementIndex, getTerminalLinkIndices, elements } = structure.carbohydrates
for (const e of loci.elements) { for (const e of loci.elements) {
......
...@@ -108,6 +108,7 @@ function eachCrossLink(loci: Loci, structure: Structure, apply: (interval: Inter ...@@ -108,6 +108,7 @@ function eachCrossLink(loci: Loci, structure: Structure, apply: (interval: Inter
let changed = false let changed = false
if (Link.isLoci(loci)) { if (Link.isLoci(loci)) {
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = Link.remapLoci(loci, structure)
for (const b of loci.links) { for (const b of loci.links) {
const indices = crossLinks.getPairIndices(b.aIndex, b.aUnit, b.bIndex, b.bUnit) const indices = crossLinks.getPairIndices(b.aIndex, b.aUnit, b.bIndex, b.bUnit)
if (indices) { if (indices) {
......
...@@ -98,6 +98,7 @@ function eachLink(loci: Loci, structure: Structure, apply: (interval: Interval) ...@@ -98,6 +98,7 @@ function eachLink(loci: Loci, structure: Structure, apply: (interval: Interval)
let changed = false let changed = false
if (Link.isLoci(loci)) { if (Link.isLoci(loci)) {
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = Link.remapLoci(loci, structure)
for (const b of loci.links) { for (const b of loci.links) {
const idx = structure.links.getBondIndex(b.aIndex, b.aUnit, b.bIndex, b.bUnit) const idx = structure.links.getBondIndex(b.aIndex, b.aUnit, b.bIndex, b.bUnit)
if (idx !== -1) { if (idx !== -1) {
...@@ -106,6 +107,7 @@ function eachLink(loci: Loci, structure: Structure, apply: (interval: Interval) ...@@ -106,6 +107,7 @@ function eachLink(loci: Loci, structure: Structure, apply: (interval: Interval)
} }
} else if (StructureElement.isLoci(loci)) { } else if (StructureElement.isLoci(loci)) {
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = StructureElement.Loci.remap(loci, structure)
// TODO mark link only when both of the link elements are in a StructureElement.Loci // TODO mark link only when both of the link elements are in a StructureElement.Loci
for (const e of loci.elements) { for (const e of loci.elements) {
OrderedSet.forEach(e.indices, v => { OrderedSet.forEach(e.indices, v => {
......
...@@ -122,6 +122,7 @@ function eachLink(loci: Loci, structureGroup: StructureGroup, apply: (interval: ...@@ -122,6 +122,7 @@ function eachLink(loci: Loci, structureGroup: StructureGroup, apply: (interval:
if (Link.isLoci(loci)) { if (Link.isLoci(loci)) {
const { structure, group } = structureGroup const { structure, group } = structureGroup
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = Link.remapLoci(loci, structure)
const unit = group.units[0] const unit = group.units[0]
if (!Unit.isAtomic(unit)) return false if (!Unit.isAtomic(unit)) return false
const groupCount = unit.links.edgeCount * 2 const groupCount = unit.links.edgeCount * 2
...@@ -137,6 +138,7 @@ function eachLink(loci: Loci, structureGroup: StructureGroup, apply: (interval: ...@@ -137,6 +138,7 @@ function eachLink(loci: Loci, structureGroup: StructureGroup, apply: (interval:
} else if (StructureElement.isLoci(loci)) { } else if (StructureElement.isLoci(loci)) {
const { structure, group } = structureGroup const { structure, group } = structureGroup
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = StructureElement.Loci.remap(loci, structure)
const unit = group.units[0] const unit = group.units[0]
if (!Unit.isAtomic(unit)) return false if (!Unit.isAtomic(unit)) return false
const groupCount = unit.links.edgeCount * 2 const groupCount = unit.links.edgeCount * 2
......
...@@ -73,6 +73,7 @@ export function eachElement(loci: Loci, structureGroup: StructureGroup, apply: ( ...@@ -73,6 +73,7 @@ export function eachElement(loci: Loci, structureGroup: StructureGroup, apply: (
if (!StructureElement.isLoci(loci)) return false if (!StructureElement.isLoci(loci)) return false
const { structure, group } = structureGroup const { structure, group } = structureGroup
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = StructureElement.Loci.remap(loci, structure)
const elementCount = group.elements.length const elementCount = group.elements.length
for (const e of loci.elements) { for (const e of loci.elements) {
const unitIdx = group.unitIndexMap.get(e.unit.id) const unitIdx = group.unitIndexMap.get(e.unit.id)
......
...@@ -46,6 +46,7 @@ export function eachNucleotideElement(loci: Loci, structureGroup: StructureGroup ...@@ -46,6 +46,7 @@ export function eachNucleotideElement(loci: Loci, structureGroup: StructureGroup
if (!StructureElement.isLoci(loci)) return false if (!StructureElement.isLoci(loci)) return false
const { structure, group } = structureGroup const { structure, group } = structureGroup
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = StructureElement.Loci.remap(loci, structure)
const unit = group.units[0] const unit = group.units[0]
if (!Unit.isAtomic(unit)) return false if (!Unit.isAtomic(unit)) return false
const { nucleotideElements, model, elements } = unit const { nucleotideElements, model, elements } = unit
......
...@@ -96,6 +96,7 @@ export function eachPolymerElement(loci: Loci, structureGroup: StructureGroup, a ...@@ -96,6 +96,7 @@ export function eachPolymerElement(loci: Loci, structureGroup: StructureGroup, a
if (!StructureElement.isLoci(loci)) return false if (!StructureElement.isLoci(loci)) return false
const { structure, group } = structureGroup const { structure, group } = structureGroup
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = StructureElement.Loci.remap(loci, structure)
const { polymerElements, model, elements } = group.units[0] const { polymerElements, model, elements } = group.units[0]
const { index, offsets } = model.atomicHierarchy.residueAtomSegments const { index, offsets } = model.atomicHierarchy.residueAtomSegments
const { traceElementIndex } = model.atomicHierarchy.derived.residue const { traceElementIndex } = model.atomicHierarchy.derived.residue
...@@ -157,6 +158,7 @@ export function eachPolymerGapElement(loci: Loci, structureGroup: StructureGroup ...@@ -157,6 +158,7 @@ export function eachPolymerGapElement(loci: Loci, structureGroup: StructureGroup
if (Link.isLoci(loci)) { if (Link.isLoci(loci)) {
const { structure, group } = structureGroup const { structure, group } = structureGroup
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = Link.remapLoci(loci, structure)
const groupCount = group.units[0].gapElements.length const groupCount = group.units[0].gapElements.length
for (const b of loci.links) { for (const b of loci.links) {
const unitIdx = group.unitIndexMap.get(b.aUnit.id) const unitIdx = group.unitIndexMap.get(b.aUnit.id)
...@@ -171,6 +173,7 @@ export function eachPolymerGapElement(loci: Loci, structureGroup: StructureGroup ...@@ -171,6 +173,7 @@ export function eachPolymerGapElement(loci: Loci, structureGroup: StructureGroup
} else if (StructureElement.isLoci(loci)) { } else if (StructureElement.isLoci(loci)) {
const { structure, group } = structureGroup const { structure, group } = structureGroup
if (!Structure.areParentsEquivalent(loci.structure, structure)) return false if (!Structure.areParentsEquivalent(loci.structure, structure)) return false
loci = StructureElement.Loci.remap(loci, structure)
const groupCount = group.units[0].gapElements.length const groupCount = group.units[0].gapElements.length
for (const e of loci.elements) { for (const e of loci.elements) {
const unitIdx = group.unitIndexMap.get(e.unit.id) const unitIdx = group.unitIndexMap.get(e.unit.id)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment