Closed hellhorse123 closed 2 months ago
That's correct, these methods are attached to a given structure, so it's not currently possible to make selections across different structures/components using these methods. There is a workaround discussed in the following response, by using the spatial hash attached to a given structure: https://github.com/nglviewer/ngl/issues/971#issuecomment-1452074968
If one structure contains a ligand and another contains a receptor, you can use some code like the following to get the neighbouring atoms.
const ligandStructure = ligComponent.structure
const spatialHash = receptorComponent.structure.spatialHash
const pocketAtomSet = receptorComponent.structure.getAtomSet(false) // an empty selection
ligandStructure.eachAtom(
ap => spatialHash.eachWithin(
ap.x, ap.y, ap.z, 4.5,
(pocketAp) => pocketAtomSet.set(pocketAp.index)
)
)
and then how to display the resulting atoms from pocketAtomSet?
I think that when you have your AtomSet ready you can give it to a representation (such as stick+ball) by setting the representation selection with your AtomSet.
That's correct, these methods are attached to a given structure, so it's not currently possible to make selections across different structures/components using these methods. There is a workaround discussed in the following response, by using the spatial hash attached to a given structure: #971 (comment)
If one structure contains a ligand and another contains a receptor, you can use some code like the following to get the neighbouring atoms.
const ligandStructure = ligComponent.structure const spatialHash = receptorComponent.structure.spatialHash const pocketAtomSet = receptorComponent.structure.getAtomSet(false) // an empty selection ligandStructure.eachAtom( ap => spatialHash.eachWithin( ap.x, ap.y, ap.z, 4.5, (pocketAp) => pocketAtomSet.set(pocketAp.index) ) )
The answer was not entirely complete, we also need to add protein.structure.getAtomSetWithinGroup
for representation all atoms.
Ultimately, this is the code that works correctly:
const loadProteinAndLigand = async () => {
const protein = await stage.loadFile(ProteinFile);
protein.addRepresentation("cartoon", { assembly: "AU" });
const ligand = await stage.loadFile(LigandFile, {});
ligand.addRepresentation("ball+stick", {});
const spatialHash = protein.structure.spatialHash;
const pocketAtomSet = protein.structure.getAtomSet(false); // an empty selection
ligand.structure.eachAtom((ap) => {
spatialHash.eachWithin(ap.x, ap.y, ap.z, 4, (atomIndex, dSq) => {
pocketAtomSet.set(atomIndex);
});
});
const atomSet2 = protein.structure.getAtomSetWithinGroup(pocketAtomSet);
protein.addRepresentation("ball+stick", {
sele: atomSet2.toSeleString(),
});
ligand.autoView();
};
getAtomSetWithinSelection and getAtomSetWithinGroup doesn't work If we add two structures into one visual scene and label protein atoms from ligand by distance. Both protein and ligand came to scene from different files. How to display protein atoms around a ligand with a radius if the ligand is loaded as a separate file into the scene? I used example from Distance-based selection