Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use an MDA Universe as a "data twin" to the blender objects #455

Open
rbdavid opened this issue Mar 26, 2024 · 3 comments
Open

Use an MDA Universe as a "data twin" to the blender objects #455

rbdavid opened this issue Mar 26, 2024 · 3 comments

Comments

@rbdavid
Copy link
Contributor

rbdavid commented Mar 26, 2024

This is a bit inspired by the idea of a "digital twin" for computer-aided manufacturing/architecture/etc but is a bit different. So here goes:

Currently, once the MolecularNodes instantiated blender object(s) are created, the associated Molecule object(s) will disappear at EOF for a script or upon killing the python interpreter panel. The Molecule object(s) are never accessible if the gui panels are used to create the blender objects. The blender objects as the final output from MN's IO and file parsing architecture. This blender object is the "visualization twin".

Currently, physical attributes associated with atoms are encoded to the blender object using biotite or MDAnalysis, depending on input files. These modules are used to gather atomic positions as well as other physical properties and encode them into the blender Object's vertices' attributes. A few of these vertex attributes, such as is_backbone, is_solvent, etc, are boolean arrays denoting regularly used atom selections. But, there are instances where more dynamic selections might be desired. Getting the indices associated with atoms for complex or dynamic selections can be challenging without the use of MDAnalysis, mdtraj, biotite, or similar libraries.

It could be really useful to have access to, for example, a MDAnalysis Universe object even after the blender object has been created. This "data twin" to the blender object could mirror all relevant changes to the blender object's attributes, such as updated atomic positions after translation/rotation. But maybe more helpful, MDA's atom_selection() could be used to dynamically select atoms, gather those atom indices, and create an attribute for the blender object's vertices that can be used in the MN geometry nodes to visualize specific selections.

Something like this "data twin" implementation would bring blender/MN up to par with pymol/VMD that have their own built-in atom selection->visualization capabilities.

@rbdavid
Copy link
Contributor Author

rbdavid commented Mar 26, 2024

I haven't dug into the implementation of the MDAnalysisSession object (in molecularnodes/io/parse/mda.py) and its associated methods. That might have all of the functionality that I'm hoping for.

I am a bit worried that the MDA session is dumped to a pickle file. Although very useful for this and many other usecases, pickle files have pretty serious security vulnerabilities. So implementing any functionality around dumping/loading pickle files should be handled very carefully.

@BradyAJohnston
Copy link
Owner

It could be really useful to have access to, for example, a MDAnalysis Universe object even after the blender object has been created. This "data twin" to the blender object could mirror all relevant changes to the blender object's attributes, such as updated atomic positions after translation/rotation. But maybe more helpful, MDA's atom_selection() could be used to dynamically select atoms, gather those atom indices, and create an attribute for the blender object's vertices that can be used in the MN geometry nodes to visualize specific selections.

This is already currently the case (kind of). There is a persistent handler that is added when you load an MD trajectory, which maintains the connection between the MDAnalysis Universe and the object it created. Whenever the frame is changed in Blender, the _update_trajectory() function is called which changes the timestep in the MDA universe, and uses the new position data to update the positions for the associated objects.

def _update_trajectory(self, frame):

This could definitely be extended to do the same for selections. The same way that currently we have a list of possible selections that can be applied when importing, we could have a list of selections that are updated each frame. the handler could take the list, generate relevant boolean arrays, then update the named attributes on the mesh.

I am a bit worried that the MDA session is dumped to a pickle file. Although very useful for this and many other usecases, pickle files have pretty serious security vulnerabilities. So implementing any functionality around dumping/loading pickle files should be handled very carefully.

I am unfamiliar with such vulnerabilities, but I am also unfamiliar with .pkl files completely. This was mostly implemented by @yuxuanzhuang who would have more knowledge on the subject. If there is a better and more secure way to serialise a universe and store it on disk for saving / reloading a .blend sesion then we could certainly look into switching to it.

@rbdavid
Copy link
Contributor Author

rbdavid commented Mar 27, 2024

I am unfamiliar with such vulnerabilities, but I am also unfamiliar with .pkl files completely. This was mostly implemented by @yuxuanzhuang who would have more knowledge on the subject. If there is a better and more secure way to serialise a universe and store it on disk for saving / reloading a .blend sesion then we could certainly look into switching to it.

I only became aware of the vulnerabilities of pickle recently -- worrisome since I pushed pickle files to a zenodo for my most recent paper. Basically, don't trust pickle files that you didn't create yourself. Upon loading a tampered pickle file, any malicious code included in that file will be run automatically. See the warning at the top of the pickle documentation (https://docs.python.org/3/library/pickle.html).

The real power of pickle is that you can write python objects (like MDA.Universe MDA.AtomGroup, etc) to a file, which upon loading into a new python session, contains the original data associated with that object (assuming the appropriate modules are loaded). In this regard, its really helpful for checkpointing complex data analyses/structures. Also, pickle files are storage efficient since they are binary files (double edged sword since not being human readable leads to security vulnerabilities).

AFAIK, there are no other python serialization modules that can write most objects to storage. It depends on what data structure you are trying to save. If the object is a data table or dictionary, then pickle doesn't need to be used; just use csv, json, or a parquet file format. But, recreating a MDA.Universe object isn't more easily done from a data table than just reloading the original input files.

This is already currently the case (kind of). There is a persistent handler that is added when you load an MD trajectory, which maintains the connection between the MDAnalysis Universe and the object it created.

I'd be interested in using the MDAnalysis Universe for all import methods. In cases of multi-frame pdbs fetched from RCSB or loaded from local, you could still use the _update_trajectory() function. In all cases, MDA's atom selection could be incredibly useful. Additionally, there are analysis suites accessible using the MDA Universe/AtomGroup that might be worth visualizing in Blender -- identification of h-bonding networks being one example that comes to mind.

This isn't a high priority task for me, but I'll try to spin up a simple working example to demonstrate potential usecases. In the end, this might not be a feature that gets added to MN but a user-adapted helper script that could be run when restarting a blender instance.

@kainszs kainszs mentioned this issue Apr 1, 2024
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants