diff --git a/src/mol-model/structure/structure/element.ts b/src/mol-model/structure/structure/element.ts index ca472c6602a91541ee0776499be3031bf2c4da5c..5e4809a5e9fae1ef367f66ab6a6f8e3a52fd9265 100644 --- a/src/mol-model/structure/structure/element.ts +++ b/src/mol-model/structure/structure/element.ts @@ -575,7 +575,7 @@ namespace StructureElement { elements.push({ groupedUnits, set: e.set, ranges: e.ranges }) }) - return { hash: (loci.structure.parent || loci.structure).hashCode, elements } + return { hash: loci.structure.root.hashCode, elements } } function getUnitsFromIds(unitIds: ArrayLike<number>, structure: Structure) { @@ -588,7 +588,7 @@ namespace StructureElement { } export function toLoci(query: Query, parent: Structure): Loci { - if (query.hash !== -1 && query.hash !== (parent.parent || parent).hashCode) { + if (query.hash !== -1 && query.hash !== parent.root.hashCode) { new Error('Query not compatible with given structure') } const elements: Loci['elements'][0][] = [] @@ -625,7 +625,7 @@ namespace StructureElement { } export function toStructure(query: Query, parent: Structure): Structure { - if (query.hash !== -1 && query.hash !== (parent.parent || parent).hashCode) { + if (query.hash !== -1 && query.hash !== parent.root.hashCode) { new Error('Query not compatible with given structure') } const units: Unit[] = [] diff --git a/src/mol-model/structure/structure/structure.ts b/src/mol-model/structure/structure/structure.ts index 08bc5c107c58568d9053260b751fce0817ec47c9..1e278d2b9c356844a4625b625fb86d5c2b97615e 100644 --- a/src/mol-model/structure/structure/structure.ts +++ b/src/mol-model/structure/structure/structure.ts @@ -146,7 +146,12 @@ class Structure { return new Structure.ElementLocationIterator(this); } - /** the root/top-most parent or `undefined` in case this is the root */ + /** The parent or itself in case this is the root */ + get root() { + return this._props.parent || this; + } + + /** The root/top-most parent or `undefined` in case this is the root */ get parent() { return this._props.parent; } @@ -629,13 +634,13 @@ namespace Structure { } /** Check if the structures or their parents are equivalent */ - export function areParentsEquivalent(a: Structure, b: Structure) { - return areEquivalent(a.parent || a, b.parent || b) + export function areRootsEquivalent(a: Structure, b: Structure) { + return areEquivalent(a.root, b.root) } /** Check if the structures or their parents are equal */ - export function areParentsEqual(a: Structure, b: Structure) { - return (a.parent || a) === (b.parent || b) + export function areRootsEqual(a: Structure, b: Structure) { + return a.root === b.root } export class ElementLocationIterator implements Iterator<StructureElement> { diff --git a/src/mol-plugin/state/transforms/representation.ts b/src/mol-plugin/state/transforms/representation.ts index 8ec62e7bd908a5634619b9ec122e09b024baff38..00349cc8db98d04dcbbfcc7adeff7b3f01d12c0a 100644 --- a/src/mol-plugin/state/transforms/representation.ts +++ b/src/mol-plugin/state/transforms/representation.ts @@ -302,23 +302,21 @@ const ExplodeStructureRepresentation3D = PluginStateTransform.BuiltIn({ }, apply({ a, params }) { const structure = a.data.source.data; - const rootStructure = structure.parent || structure; - const unitTransforms = new StructureUnitTransforms(rootStructure); + const unitTransforms = new StructureUnitTransforms(structure.root); explodeStructure(structure, unitTransforms, params.t); return new SO.Molecule.Structure.Representation3DState({ state: { unitTransforms }, - initialState: { unitTransforms: new StructureUnitTransforms(rootStructure) }, - info: rootStructure, + initialState: { unitTransforms: new StructureUnitTransforms(structure.root) }, + info: structure.root, source: a }, { label: `Explode T = ${params.t.toFixed(2)}` }); }, update({ a, b, newParams, oldParams }) { const structure = a.data.source.data; - const rootStructure = structure.parent || structure; - if (b.data.info !== rootStructure) return StateTransformer.UpdateResult.Recreate; + if (b.data.info !== structure.root) return StateTransformer.UpdateResult.Recreate; if (oldParams.t === newParams.t) return StateTransformer.UpdateResult.Unchanged; const unitTransforms = b.data.state.unitTransforms!; - explodeStructure(rootStructure, unitTransforms, newParams.t); + explodeStructure(structure.root, unitTransforms, newParams.t); b.label = `Explode T = ${newParams.t.toFixed(2)}`; b.data.source = a; return StateTransformer.UpdateResult.Updated; diff --git a/src/mol-plugin/ui/sequence/hetero.ts b/src/mol-plugin/ui/sequence/hetero.ts index e42017d80586f99c1a62bef931b9b77e3fb2f3b8..edf2ee50c5822ae664c7558e431b976ea59c812e 100644 --- a/src/mol-plugin/ui/sequence/hetero.ts +++ b/src/mol-plugin/ui/sequence/hetero.ts @@ -26,7 +26,7 @@ export class HeteroSequenceWrapper extends SequenceWrapper<StructureUnit> { let changed = false const { structure, unit } = this.data if (StructureElement.isLoci(loci)) { - if (!Structure.areParentsEquivalent(loci.structure, structure)) return false + if (!Structure.areRootsEquivalent(loci.structure, structure)) return false loci = StructureElement.Loci.remap(loci, structure) for (const e of loci.elements) { @@ -39,7 +39,7 @@ export class HeteroSequenceWrapper extends SequenceWrapper<StructureUnit> { } } } else if (Structure.isLoci(loci)) { - if (!Structure.areParentsEquivalent(loci.structure, structure)) return false + if (!Structure.areRootsEquivalent(loci.structure, structure)) return false if (apply(Interval.ofBounds(0, this.length))) changed = true } diff --git a/src/mol-plugin/ui/sequence/polymer.ts b/src/mol-plugin/ui/sequence/polymer.ts index 0e5f1a26db92772cc621f8060d27e5a1075f9d8e..fa25a3255f229c4a0d8d89cef2a5ae42db302c2a 100644 --- a/src/mol-plugin/ui/sequence/polymer.ts +++ b/src/mol-plugin/ui/sequence/polymer.ts @@ -37,7 +37,7 @@ export class PolymerSequenceWrapper extends SequenceWrapper<StructureUnit> { let changed = false const { structure, unit } = this.data if (StructureElement.isLoci(loci)) { - if (!Structure.areParentsEquivalent(loci.structure, structure)) return false + if (!Structure.areRootsEquivalent(loci.structure, structure)) return false loci = StructureElement.Loci.remap(loci, structure) const { offset } = this.sequence @@ -49,7 +49,7 @@ export class PolymerSequenceWrapper extends SequenceWrapper<StructureUnit> { } } } else if (Structure.isLoci(loci)) { - if (!Structure.areParentsEquivalent(loci.structure, structure)) return false + if (!Structure.areRootsEquivalent(loci.structure, structure)) return false if (apply(this.observed)) changed = true } diff --git a/src/mol-plugin/util/interactivity.ts b/src/mol-plugin/util/interactivity.ts index 41289157b72ef799122c586740b5b9dfd02ace1d..31babee35563feeb2b201004865e88f0fa347d20 100644 --- a/src/mol-plugin/util/interactivity.ts +++ b/src/mol-plugin/util/interactivity.ts @@ -101,7 +101,7 @@ namespace Interactivity { } if (Structure.isLoci(loci)) { // convert to StructureElement.Loci of root structure - loci = Structure.toStructureElementLoci(Structure.Loci(loci.structure.parent || loci.structure)) + loci = Structure.toStructureElementLoci(Structure.Loci(loci.structure.root)) } if (StructureElement.isLoci(loci) && loci.structure.parent) { // ensure the root structure is used diff --git a/src/mol-plugin/util/structure-overpaint-helper.ts b/src/mol-plugin/util/structure-overpaint-helper.ts index 120ea8ef0405d8d5011ae08774b8ee855bc6c80e..47b3399f8e76b92e40fd84111ea47955dad9a20a 100644 --- a/src/mol-plugin/util/structure-overpaint-helper.ts +++ b/src/mol-plugin/util/structure-overpaint-helper.ts @@ -34,9 +34,8 @@ export class StructureOverpaintHelper { const overpaint = state.select(StateSelection.Generators.ofTransformer(StateTransforms.Representation.OverpaintStructureRepresentation3D, r.transform.ref).withTag(OverpaintManagerTag)); const structure = r.obj!.data.source.data - const rootStructure = structure.parent || structure - callback(update, r, rootStructure, overpaint[0]) + callback(update, r, structure.root, overpaint[0]) } await this.plugin.runTask(state.updateTree(update, { doNotUpdateCurrent: true })); diff --git a/src/mol-repr/structure/complex-representation.ts b/src/mol-repr/structure/complex-representation.ts index bdd23b1ae20f49fd3d60785b78a7f4eb8e9c2b0b..120e7332dc1569eabbc2dc60c513007994a16aae 100644 --- a/src/mol-repr/structure/complex-representation.ts +++ b/src/mol-repr/structure/complex-representation.ts @@ -57,7 +57,7 @@ export function ComplexRepresentation<P extends StructureParams>(label: string, function mark(loci: Loci, action: MarkerAction) { if (!_structure) return false if (!StructureElement.isLoci(loci) && !Link.isLoci(loci)) return false - if (!Structure.areParentsEquivalent(loci.structure, _structure)) return false + if (!Structure.areRootsEquivalent(loci.structure, _structure)) return false if (StructureElement.isLoci(loci)) { loci = StructureElement.Loci.remap(loci, _structure) } else if (Link.isLoci(loci)) { diff --git a/src/mol-repr/structure/complex-visual.ts b/src/mol-repr/structure/complex-visual.ts index 7770c03f517635c5175a9cd6f112a50b18644536..7366c99e958d8a64e503c2571f25c9b9c9cebaa8 100644 --- a/src/mol-repr/structure/complex-visual.ts +++ b/src/mol-repr/structure/complex-visual.ts @@ -165,7 +165,7 @@ export function ComplexVisual<G extends Geometry, P extends ComplexParams & Geom } function lociApply(loci: Loci, apply: (interval: Interval) => boolean) { - if (isEveryLoci(loci) || (Structure.isLoci(loci) && Structure.areParentsEquivalent(loci.structure, currentStructure))) { + if (isEveryLoci(loci) || (Structure.isLoci(loci) && Structure.areRootsEquivalent(loci.structure, currentStructure))) { return apply(Interval.ofBounds(0, locationIt.groupCount * locationIt.instanceCount)) } else { return eachLocation(loci, currentStructure, apply) diff --git a/src/mol-repr/structure/units-representation.ts b/src/mol-repr/structure/units-representation.ts index 63e2066044b5ee970df11f519088350dbf53050c..9bc1adc3e3865225057c07533e2d87f5e5746d8e 100644 --- a/src/mol-repr/structure/units-representation.ts +++ b/src/mol-repr/structure/units-representation.ts @@ -166,7 +166,7 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R let changed = false if (!_structure) return false if (!StructureElement.isLoci(loci) && !Link.isLoci(loci)) return false - if (!Structure.areParentsEquivalent(loci.structure, _structure)) return false + if (!Structure.areRootsEquivalent(loci.structure, _structure)) return false if (StructureElement.isLoci(loci)) { loci = StructureElement.Loci.remap(loci, _structure) if (loci.elements.length === 0) return false diff --git a/src/mol-repr/structure/units-visual.ts b/src/mol-repr/structure/units-visual.ts index b440d393fe93c42b176458a3f6565da5c9e3ec37..b6b38d23da8910887297109ffa2fd1c05df6d019 100644 --- a/src/mol-repr/structure/units-visual.ts +++ b/src/mol-repr/structure/units-visual.ts @@ -215,7 +215,7 @@ export function UnitsVisual<G extends Geometry, P extends UnitsParams & Geometry } function lociApply(loci: Loci, apply: (interval: Interval) => boolean) { - if (isEveryLoci(loci) || (Structure.isLoci(loci) && Structure.areParentsEquivalent(loci.structure, currentStructureGroup.structure))) { + if (isEveryLoci(loci) || (Structure.isLoci(loci) && Structure.areRootsEquivalent(loci.structure, currentStructureGroup.structure))) { return apply(Interval.ofBounds(0, locationIt.groupCount * locationIt.instanceCount)) } else { return eachLocation(loci, currentStructureGroup, apply) diff --git a/src/mol-repr/structure/visual/util/polymer.ts b/src/mol-repr/structure/visual/util/polymer.ts index 33f99c023eeaf4d6d8d94483a70b56c0023a4360..61f369720ae7a67976af5345429102d28ca14eb0 100644 --- a/src/mol-repr/structure/visual/util/polymer.ts +++ b/src/mol-repr/structure/visual/util/polymer.ts @@ -162,7 +162,7 @@ export function eachPolymerGapElement(loci: Loci, structureGroup: StructureGroup let changed = false if (Link.isLoci(loci)) { const { structure, group } = structureGroup - if (!Structure.areParentsEquivalent(loci.structure, structure)) return false + if (!Structure.areRootsEquivalent(loci.structure, structure)) return false loci = Link.remapLoci(loci, structure) const groupCount = group.units[0].gapElements.length for (const b of loci.links) { @@ -177,7 +177,7 @@ export function eachPolymerGapElement(loci: Loci, structureGroup: StructureGroup } } else if (StructureElement.isLoci(loci)) { const { structure, group } = structureGroup - if (!Structure.areParentsEquivalent(loci.structure, structure)) return false + if (!Structure.areRootsEquivalent(loci.structure, structure)) return false loci = StructureElement.Loci.remap(loci, structure) const groupCount = group.units[0].gapElements.length for (const e of loci.elements) {