Open
Description
I am trying to add a transparency layer to my displayed structure by copying the implementation in alphafold-transparency.ts and adapting it to my code structure.
When applying the transforms to a structure, the operation fails with the error "No suitable parent found".
Using the select, highlight, or other visual methods works just fine.
Do you have a pointer on how I can make it work?
Is there a specific order of operations I am missing or a different way to reference parents I must add?
Thank you very much in advance!
Tech Stack
I am using:
- Svelte
- PDBe-Molstar-component 3.3.2
- Molstar 4.10.0
Reproduction Steps
- Initialize PDBe-MolStar viewer with an AlphaFold structure
- Attempt to apply confidence visualization via
applyConfidenceVisualization()
- The operation fails with error: "No suitable parent found for 'transparency-{parentRef}'"
Code Snippets
export class MolstarWrapper {
private viewer: any;
constructor(viewerElement: any) {
this.viewer = viewerElement;
}
async applyConfidenceVisualization() {
await this.whenReady();
const plugin = this.plugin;
if (!plugin) {
console.warn("No transparency plugin found");
return;
}
const pLDDT = 70;
const transparency = 1;
const assemblyRef =
this.plugin.managers.structure.hierarchy.current.structures[0].cell
.transform.ref;
const structure =
plugin.managers.structure.hierarchy.current?.refs.get(assemblyRef);
if (!structure) {
console.warn("No structure found");
return;
}
return plugin.dataTransaction(
async (ctx: any) => {
const loci = this.viewer.viewerInstance.getLociByPLDDT(pLDDT);
await this.setStructureTransparency(
plugin,
structure.components,
transparency,
loci,
);
},
{ canUndo: "Apply Transparency" },
);
}
private getFilteredBundle(
layers: Transparency.BundleLayer[],
structureRef: Structure,
) {
const transparency = Transparency.ofBundle(layers, structureRef.root);
const merged = Transparency.merge(transparency);
return Transparency.filter(
merged,
structureRef,
) as Transparency<StructureElement.Loci>;
}
private async updateRepresentations(
plugin: PluginContext,
components: StructureComponentRef[],
callback: TransparencyEachReprCallback,
) {
const state = plugin.state.data;
const update = state.build();
for (const c of components) {
for (const r of c.representations) {
const transparency = state.select(
StateSelection.Generators.ofTransformer(
StateTransforms.Representation
.TransparencyStructureRepresentation3DFromBundle,
r.cell.transform.ref,
).withTag(TransparencyManagerTag),
);
await callback(update, r.cell, transparency[0]);
}
}
update.commit();
}
private async setStructureTransparency(
plugin: PluginContext,
components: StructureComponentRef[],
value: number,
loci: StructureElement.Loci,
) {
await this.updateRepresentations(
plugin,
components,
async (update, repr, transparencyCell) => {
const structure = repr.obj!.data.sourceData;
if (Loci.isEmpty(loci) || isEmptyLoci(loci)) {
return;
}
const layer = {
bundle: StructureElement.Bundle.fromLoci(loci),
value,
};
if (transparencyCell) {
const bundleLayers = [
...transparencyCell.params!.values.layers,
layer,
];
const filtered = this.getFilteredBundle(bundleLayers, structure);
update.to(transparencyCell).update(Transparency.toBundle(filtered));
} else {
const parentRef = repr.transform.ref;
const parentNode = plugin.state.data.tree.transforms.get(parentRef);
if (!parentNode) {
throw new Error(`Parent node ${parentRef} not found in state tree`);
}
// Create the transparency transform params
const filtered = this.getFilteredBundle([layer], structure);
const transparencyRef = `transparency-${parentRef}`;
const params = {
...Transparency.toBundle(filtered),
parent: parentRef,
};
update
.to(parentRef)
.apply(
StateTransforms.Representation
.TransparencyStructureRepresentation3DFromBundle,
params,
{
tags: TransparencyManagerTag,
ref: transparencyRef,
},
);
}
},
);
}
Since I use Svelte, I have to use the web component:
<pdbe-molstar
style="height: 100%; width: 100%; z-index: 4;"
bind:this={viewerElement}
custom-data-url={structureUrl}
custom-data-format={format}
custom-data-binary={binary}
expanded={false}
pdbe-logo={false}
domain-annotation={true}
hide-controls={true}
sequence-panel={false}
alphafold-view={true}
>
</pdbe-molstar>
Expected Behavior
Set the transparency for individual residues and keep the pLDDT-based coloring
Actual Behavior
Display the structure with pLDDT-based coloring and fail with:
Error: No suitable parent found for 'transparency-etNZCwaao0fWvB2reMaljA'
i pdbe-molstar-component.js:25
J pdbe-molstar-component.js:25
A pdbe-molstar-component.js:25
_updateTree pdbe-molstar-component.js:25
updateTree pdbe-molstar-component.js:25
p pdbe-molstar-component.js:25
u pdbe-molstar-component.js:25
run pdbe-molstar-component.js:25
runTask pdbe-molstar-component.js:25
commit pdbe-molstar-component.js:25
updateRepresentations MolstarWrapper.ts:300
setStructureTransparency MolstarWrapper.ts:309
applyConfidenceVisualization MolstarWrapper.ts:255
transaction pdbe-molstar-component.js:25
p pdbe-molstar-component.js:25
u pdbe-molstar-component.js:25
run pdbe-molstar-component.js:25
runTask pdbe-molstar-component.js:25
dataTransaction pdbe-molstar-component.js:25
applyConfidenceVisualization MolstarWrapper.ts:252
...
Even though:
- The parent reference exists in the state tree (verified via logging)
- The parent node is accessible and valid
- The transform parameters include the correct parent reference
Metadata
Metadata
Assignees
Labels
No labels