Closed dotsdl closed 8 years ago
@dotsdl
for your curiosity, you can check my fork (different API with @arose repo):
https://github.com/hainm/nglview
import nglview as nv
from MDAnalysis import Universe
import numpy as np
u = Universe('tz2.parm7', 'tz2.nc')
all_atoms = u.select_atoms('all')
# load coordinates to memory
xyz = np.asarray([all_atoms.coordinates() for frame in u.trajectory], dtype='f8')
# create nv.Structure
with open('tz2_0.pdb') as fh:
text = fh.read()
structure = nv.Structure(text)
traj = nv.Trajectory(xyz=xyz, topology=structure)
view = nv.TrajectoryViewer(traj)
view.add_representation('licorice')
view
Per atom selection, ngl has its own one, so I am not sure if It can use mdanalysis. But what I have in mind (for mdanalysis users) is to get atom indices (np array) from AtomGroup and pass to nglview.
@hainm Yeah, I know there are ways of using it as-is, but I was curious whether there was interest in tightening up integration in a less clunky way with MDAnalysis on this end. We could always build wrapper functions/classes as an MDAnalysis.visualization
submodule if this project doesn't want to do it.
but I was curious whether there was interest in tightening up integration in a less clunky way with MDAnalysis on this end.
yes, @arose and I think so.
What's in my mind
import nglview as nv
traj = nv.io.from_pytraj(its_object)
traj = nv.io.from_mdanalysis(its_object)
traj = nv.io.from_mdtraj(its_object)
@arose has different approach (more object-oriented than mine).
Hi, cool to see more interest in this! My goal with the API is to provide a way to pass the data as raw/flat (numpy) arrays into the viewer and then have some convenience functions or objects to get data from various libraries.
Currently the NGL viewer can handle raw coordinate data but needs the topology as a pdb, gro or mmcif file. However I am refactoring the NGL viewer so that it can handle the topology in a binary format (private branch so far). As to atom selections, in another refactoring effort I am introducing bit-sets to NGL which will allow very efficient transfer of atom selections from libraries to the viewer. My opinion is that the libraries should use their own selection language (though I would very much like to see a common shared language eventually).
I hope to find some time this weekend to cleanup the API and integrate support for MDAnalysis. For the time being I wont be doing MD simulations or analysis myself. But I am very actively developing the NGL Viewer itself and will ensure support for MD data. Also, I am more then willing to share and discuss my ideas on how to push the Jupyter integration forward! In particular, efficient data transfer between kernel and browser will help (https://github.com/arose/nglview/issues/3). Feel free to contact me!
@hainm I will definitely have a look on what you have done, esp. API wise and will discuss it with you. I certainly like the addition of ready-to-use notebook examples!
@dotsdl Is MDAnalysis Python 2 only for now? I get an error with Python 3 and MDAnalysis 0.13.0
File "/home/arose/miniconda3/lib/python3.4/site-packages/MDAnalysis/lib/mdamath.py", line 161
A, B, C = [norm(v) for v in x, y, z]
^
SyntaxError: invalid syntax
@dotsdl Is there a way in MDAnalysis to get a specific frame with iterating over all previous?
for ts in universe.trajectory:
print ts.frame
Or is iterating fast and the data is only gather when attributes of the frame are accessed? Otherwise I would follow @hainm example and load everything into a numpy array.
@arose All of this sounds great, though I'll admit digging through the plumbing of the Jupyter notebook is not something I'm familiar with.
MDAnalysis is still Python 2-only, though we're almost fully Python 3 compatible. Is this library Python 3 only?
Getting to a specific frame can be done by indexing:
import MDAnalysis as mda
from MDAnalysisTests.datafiles import GRO, XTC
u = mda.Universe(GRO, XTC)
# go to frame 3 (0-based)
u.trajectory[3]
# positions reflect coordinates at the current frame
u.atoms.positions
So I imagine the viewer could display whatever the current frame is, and changing the frame could change the viewer, and vice-versa?
MDAnalysis is still Python 2-only, though we're almost fully Python 3 compatible. Is this library Python 3 only?
It should work on both Python 2 and 3. However the machine I currently have has only Python 3, so, just an annoyance for me.
So I imagine the viewer could display whatever the current frame is, and changing the frame could change the viewer, and vice-versa?
The frame can be changed from the Python and the Browser side. When you create the viewer in the notebook you get a widget object back that has a synced frame
attribute. The widget object in turn would be linked to the Universe.
Two more question, then I can quickly add a mda.Universe wrapper.
@arose the frame count can be gotten from Universe.trajectory.n_frames
or equivalently len(Universe.trajectory)
. Getting the topology as a string is possible using MDAnalysis.lib.util.NamedStream
, perhaps like so:
import MDAnalysis as mda
from MDAnalysisTests.datafiles import GRO, XTC
import cStringIO
u = mda.Universe(GRO, XTC)
f = mda.lib.util.NamedStream(cStringIO.StringIO(), 'lol.pdb')
# add PDB output to the named stream
with mda.Writer(f, u.atoms.n_atoms, multiframe=False) as W:
W.write(u.atoms)
# extract from the stream
f.readlines()
Does that help? Let me know if there's anything else you need, or if you want me to have a look at some prototypes. Excited for this!
@dotsdl Yes this helps. I just pushed an untested implementation. You can check the master branch out, install it (python setup.py develop
) and run the following in a notebook -- hopefully it works...
import nglview as nv
import MDAnalysis as mda
from MDAnalysisTests.datafiles import GRO, XTC
u = mda.Universe(GRO, XTC)
w = nv.show_mdanalysis(u)
w
@arose hmmm...the widget shows up, and I can push play and watch the slider move, and moving the slider is reflected by a change in the active frame of the trajectory reader. However, I don't see any molecule representation displayed. Any ideas for troubleshooting this?
w.count
?w.add_representation( "line", "*" )
help?I do get a DeprecationWarning
:
/home/alter/.local/lib/python2.7/site-packages/ipywidgets/widgets/widget.py:513: DeprecationWarning: on_trait_change is deprecated: use observe instead
self.on_trait_change(_validate_border, ['border_width', 'border_style', 'border_color'])
w.count
gives 10
Doing w.add_representation("line", "*")
didn't change the situation.
Cleaning out my .local/lib/python2.7/site-packages
; it's a bit crufty. If that doesn't work I'll do the smart thing and use a virtualenv.
Does the pdbid example work?
import nglview
struc = nglview.PdbIdStructure( "3pqr" ) # load file from RCSB PDB
w = nglview.NGLWidget( struc ) # create widget
w # display widget
It does. :D
Then I suspect the code to get the pdb string does not... Would you mind trying the following in https://github.com/arose/nglview/blob/master/nglview/__init__.py#L223
def get_structure_string(self):
import MDAnalysis as mda
u = self.universe
u.trajectory[0]
fd, fname = tempfile.mkstemp(suffix=".pdb")
# add PDB output to the named stream
with mda.Writer(fd, u.atoms.n_atoms, multiframe=False) as W:
W.write(u.atoms)
# extract from the stream
pdb_string = os.fdopen(fd).read()
return pdb_string
Played with this a bit on the plane, and still couldn't get it to work. Perhaps something's wrong with the PDB files MDAnalysis writes with respect to what nglview expects? Something related to this issue?
Back at my desktop machine with Python 2 set up. Fixed it in 724c64c567917f6a15e601b115503dbf45fbbb54.
Played with this a bit on the plane, and still couldn't get it to work. Perhaps something's wrong with the PDB files MDAnalysis writes with respect to what nglview expects? Something related to this issue?
NGL does not care about the atomname
alignment.
why is there long bond?
why is there long bond?
These are just the coordinates and bonds from mda. I suspect they are not centered respecting PBC by default in mda. Right @dotsdl?
I am not sure if nglview should be opinionated about it or just display what it is given. I lean to the latter.
I lean to the latter.
yeah, VMD does not care too, it's up to user.
@arose
Correct. This is the result I expect. I made some modifications in #30 so that the wrapper can also just take an AtomGroup, since for large systems there's no need to dump the whole thing in.
Quick question while I'm playing with one of my big membrane protein systems: what's the best way to get nglview
to render non-protein molecules? Like ions and lipids or even waters?
for ions and waters, I normally use 'licorice'
view.add_representation('licorice', color='red')
not sure about lipid (but I am interested in @arose's answer too).
Ah...got it. Had to look closely at the selection language and the representations available. I can view everything I want to see in my system now. This is too cool!
licorice
/ball+stick
and spacefill
are but there are also line
and point
representation types which are not as demanding.
Ah...got it. Had to look closely at the selection language and the representations available. I can view everything I want to see in my system now. This is too cool!
do you mind sharing your image? curious about lipid representation in your case.
:-)
It would be awesome to be able to pass an
MDAnalysis.Universe
object into a wrapper object similar tonglview.MDTrajTrajectory
, with the wrapper pulling coordinate information through that object. Haven't looked in detail at the library to see the best way to go about it, but it I imagine there could be pretty wild and wonderful ways to take advantage of MDAnalysis' feature set, including perhaps making selections usingAtomGroup
objects.