nglviewer / ngl

WebGL protein viewer
http://nglviewer.org/ngl/
MIT License
663 stars 167 forks source link

Select atom by location in biological assemblies with duplicate chains #619

Open samirelanduk opened 5 years ago

samirelanduk commented 5 years ago

Currently the atom selection language lets you specify chain/residue/name etc. to determine which atom you are talking about, and is quite comprehensive. When dealing with the raw asymmetric unit coordinates, this is more than enough to select an atom with no ambiguity.

However, when biological assemblies are generated, chains get duplicated but keep the same ID. This means that many atoms no longer have a unique string that can be used to identify them.

An example of where this is an issue is here. The blue lines are supposed to go from a central metal atom to specified coordinating atoms, but in this case the identifier for the coordinating atoms can apply to the atom next to the metal, or one on the other side of the structure - the latter being selected in this case, meaning that you get coordination bonds stretching across the structure.

(I'm aware you can use the contact representation, but I prefer to manually specify which atoms are in contact.)

If there was a way to specify an atom by location, that would enable atoms to be uniquely identified even in biological assemblies. I apologise for only raising this as an issue rather than a pull request, but my JS isn't really up to task currently! Would it be a major undertaking? Or is there maybe an other way to solve this problem?

fredludlow commented 5 years ago

Unfortunately I don't think this is fixable, but see below for a workaround. My understanding is that the biological unit transforms are applied at a webgl level rather than duplicating atoms/chains etc - this way you can draw viruses while using (relatively) little memory.

The easiest solution is probably to use the assembly file from the PDB, (see issue #459), in this particular case: https://files.rcsb.org/download/1A6F.pdb2.gz

This file has 2 models (which will exist as separate models of the same structure and can be addressed with /0, /1 etc in the selection language).

NB: This negates all the benefit of the webgl trick above, so use with caution for big structures!

samirelanduk commented 5 years ago

Ah, that's a shame! Does that mean that the equivalent atoms are literally the same object in memory?

For my particular problem, is there a way to draw lines between two points in space, rather than between two atoms? That is, instead of going from atom A to atom B, go from position (x1, y1, z1) to (x2, y2, z2)?

arose commented 5 years ago

Does that mean that the equivalent atoms are literally the same object in memory?

Hi @samirelanduk, yes I am afraid so. It is a long standing issue. However in Mol* (molstar.org) we have handled it and there you can address every every atom in every instance of a chain. And the best part, it still uses the WebGL trick to efficiently draw viruses and the like.

is there a way to draw lines between two points in space

Yes, use the Shape class and .addCylinder or .addWideline

samirelanduk commented 5 years ago

Molstar looks great - is that intended to ultimately be the successor to NGL?

The Cylinder solution worked perfectly thanks. I'm just having trouble zooming to a particular location using cooridnates though. Where before I would use:

component.autoView(residues);

...where residues is some atom selection string. Is there any equivalent using something like:

component.autoView([10.0, 11.2, -2.3);

...for example? I tried playing around with setPosition() and setScale() but they didn't seem to have much effect.

arose commented 5 years ago

Molstar looks great - is that intended to ultimately be the successor to NGL?

Yes!

I tried playing around with setPosition() and setScale() but they didn't seem to have much effect.

Those actually move the component around in the scene, which is not what you want I think.

Try something like this.stage.animationControls.zoomMove(center, zoom, duration)