View on GitHub

nezix.github.io

Practical UnityMol tutorial

UnityMol Executables can be downloaded here

UnityMol is a molecular viewer that can be used in a standard desktop context or in a Virtual Reality (VR) context. For now, there are one executable for the VR version and one for the desktop version but the same code base is used.

UnityMol is also a molecular visualization platform to prototype and develop new molecular representations and custom interaction metaphores. It is developed mainly in C# in the Unity game engine.

Molecular input files currently supported are: PDB/mmCIF/GRO/Mol2/XYZ/SDF and XTC for trajectory files, OpenDX for potential maps.

This tutorial gives a short introduction to UnityMol 1.1.2 in the form of a simplified documentation / tutorial.


Interface

UnityMol is currently based on one window menu with retractable sub-menus:

The top right button with an arrow hides the whole menu.

Loaded molecule buttons

When loading a molecule, several selections and representations will be created by default (if the showDefaultRep flag is on for the load and fetch API functions):

Each loaded molecule will have this line :

Use the left arrow to hide all the selection buttons of this molecule.

Selection / Representation buttons

The selection button can be unfolded to show two input fields :

The (+) button allows to add representations to the corresponding selection. The (x) button deletes the selection and all the representations of this selection.

You can set or unset the current selection by clicking on the selection button, it will make the button darker and will show an outline around atoms of the selection. This outline is not updated when reading a trajectory for performance reasons for now.

Representations

First, the eye button hides/shows the corresponding representation. You can also delete a representation using the (x) button.

Note that if you modify the selection, you have to click on the eye button to update the representation.

By clicking on the selection label, the menu unfolds and you can tweak the different parameters of the representation :

Here is a list of representations available in UnityMol:


Python console

To make the python console appear (or disappear), you have to use the CTRL + <space bar> key combo or use the top left arrow.

To use it see Python Console

The console is using IronPython, a C# interpreter that compiles python but also gives you access to C# objects. This means that you can call C# / Unity functions from the console like: GameObject.Find("Directional Light")


Getting started

Loading

Let’s load a molecule, do some selections, create some representations and modify their properties.

In the console, type :

s = fetch("1bl8")
print(s)

You can also use the PDBID input field of the menu in the Input sub-menu:

This should show you something close to this:

Coloring

Now let’s change the color of the cartoon representation created on the “1bl8_protein_or_nucleic” selection by clicking on the cartoon line to expand the options and clicking on “By chain” button:

This is equivalent to do colorByChain("1bl8_protein_or_nucleic", "c") in the console.

You can also color the full representations using the color picker in the menu that is equivalent to calling colorSelection("1bl8_protein_or_nucleic", "c", Color.red).

UnityMol provides a lot of different color functions that are not always available in the UI:

colorByAtom("selName", "c")
colorByResidue("selName", "c")
colorByChain("selName", "c")
colorByHydrophobicity("selName", "c")
colorBySequence("selName", "c")
colorByCharge("selName", "c")
colorByResidueType("selName", "c")
colorByResidueCharge("selName", "c")
colorByBfactor("selName", "c")

To modify default values for UnityMol colors, you can modify the file that is loaded when UnityMol starts: “StreamingAssets/customUnityMolColors.txt”. This files overwrites “defaultUnityMolColors.txt” that is also loaded at start.

The format is: AtomName #HexadecimalColor radius. For example: H #ffffff 1.2

Adding representations to selections

We can add a “all-atoms” representation by adding the “Hyperball” representation: click on the (+) button of the “1bl8_protein_or_nucleic” selection button and click on “Hyperball” in the dropdown menu:

This is equivalent to do showSelection("1bl8_protein_or_nucleic", "hb") in the console.

Let’s color carbon atoms in the hyperball representations in gray: colorAtomType("1bl8_protein_or_nucleic", "hb", "C", Color.gray).

Show/hide buttons for representations are calling showSelection("selName", "repType") and hideSelection("selName", "repType") functions. Delete buttons are calling deleteRepresentationInSelection("selName", "repType") or deleteRepresentationInSelection("selName").

To hide all the representations of a selection you can call hideSelection("selName").

To hide all representations of a structure you can call hideStructureAllRepresentations("structureName"), the opposite is showStructureAllRepresentations("structureName").

You can also hide representations in all the selections based on the representation type: hide("c") will hide all cartoon representations.

Adding hydrogens with Reduce

Let’s add hydrogens to this molecule with the Reduce method by clicking on the “H” button next to the name of our protein. This is equivalent to do addHydrogensReduce("1bl8") or if you don’t know the name of the molecule you can use the ‘s’ variable storing the UnityMolStructure when we loaded the molecule :addHydrogensReduce(s.name). We can also use the last loaded molecule by doing: addHydrogensReduce(last().name).

This should update the representations to this:

Note that the number of atoms in some selections has changed.

Zooming / Center

To zoom on a part of the molecule, you can double click on one atom of the residue if it is displayed. You can also double click the selection button (since UnityMol 1.1.1). From the console, you can do centerOnSelection("1bl8_water", lerp=True).

You can also click on a selection to make it the “current selection” and click on the “Center on Selection” button under the “View” menu.

Translation / Rotation (desktop)

On desktop, you can use the mouse button to rotate all molecules with the left button, zoom in/out with the right button and translate.

If several molecules are loaded, you can only rotate one molecule by clicking on “R” + left button. To only translate a molecule press “T” and left click on the molecule.

Selection language

Let’s select only a part of the molecule and display it as a transparent surface. There are several ways to create selections:

Now let’s show the newly created selection as a surface. Click on the (+) button and select Surface (MSMS) or enter showSelection("chainA", "s", SurfMethod.MSMS).

The surface can be displayed as a wireframe or with a transparent material by clicking on the surface label to expand the properties sub-menu then clicking on the “Transparent” button. You can also enter setTransparentSurface("chainA") or setTransparentSurface("chainA", 0.30) in the console.

Let’s color the surface in red: colorSelection("chainA", "s", Color.red) or colorSelection("chainA", "s", Color(1.0,0.0,0.0,1.0)

Hide the cartoon representation with hideSelection("1bl8_protein_or_nucleic", "c") and change the background color with bg_color(Color.black) or bg_color("black") or bg_color(Color(0,0,0,1))

You should have something close to this:

For a better overview of all the possibilities of the selection language please see here and here.

Select in range

To select atoms around 5.0 Angstrom of the water molecule of 1BL8 type:

select("not water and within 5.0 resname HOH", "closeToWat")
showSelection("closeToWat", "l")#show this selection as lines

You can now re-use this selection to create new selections:

select("not closeToWat", "AllButCloseToWat")

Saving command history

To save the current selections and representations to be able to share it or reload the commands you can click on the “Utils” -> “Save script” button. This will save all the commands that we executed, using the UI or the console. Some optimization work can be done to clear unnecessary commands by editing this file by hand.

You can also call the saveHistoryScript("mypath.py") command from the console to save the history of commands.

You can reload the file containing a list of commands by doing loadHistoryScript("mypath.py") or clicking on the “Load Script” from the “Utils” menu.

Taking pictures/videos

You can take a screenshot by clicking on the “Save image” button in the “View” menu. This will create a folder called UnityMolScreenshort on your desktop and save the image to it with a 1080p resolution. You can also use screenshot("mypath.png", 1920, 1080, transparentBG=False) command.

Videos can be taken via the command startVideo("mypath.mp4", 1920, 1080, 60) and stopped with stopVideo(). To have an example of a script to render an animation take a look at this script.

Please see this page for more information.

Scripting

The UnityMol console combined to the python API provides a way to perform simple actions but also complicated and convoluted scripts.

For example, let’s clean all loaded molecules by doing reset() and load 3EAM without displaying a representation fetch("3eam", showDefaultRep=False).

We are going to create a selection by chain and color each chain.

s = last() #Get the lastly loaded structure
colors = [Color(1,0,0,1), Color(1, 1, 0, 1), Color(1,1,1,1), Color(0,1,1,1), Color(0,0,1,1)] #Create a list of colors
idC = 0
for c in s.currentModel.chains.Values: #Loop over the chains of the molecule
    sel = select(s.name+" and chain "+c.name, "Chain"+c.name) #Create a selection for the chain
    showSelection(sel.name, "c") #Show the selection as a cartoon
    colorSelection(sel.name, "c", colors[min(idC, len(colors)-1)])
    idC+=1

For a complete set of all API commands please read this page !


Trajectory / Model Player

UnityMol supports loading XTC trajectories using libxdrfile2. The first time a trajectory is loaded, a binary .offset file is created to store the position of each frame in the file. This allows to “jump” in the file without loading the whole trajectory in memory.

To load a trajectory, press the “Load” button from the Input menu and set the file filters to “Trajectory files” or use: loadTraj("structureName", "mypathToXTCFile.xtc").

By default, UnityMol loads the trajectory on the last loaded molecule when using the “Load” button.

This sub-menu should be displayed under the loaded molecule UI row:

A similar menu is displayed when a molecule with several models is loaded. There are two ways to load a molecular file with several models. By default, UnityMol parses a PDB/mmCIF/GRO file with modelsAsTraj = True meaning that the first model is read and only the new positions of the next frames are stored. The second way is to really store each model in a different UnityMolModel.

UnityMol allows to have models with different number of atoms for the same molecule only if the modelsAsTraj flag is false.

The smooth button interpolates between 2 frames using a linear interpolation. Cubic interpolation uses 4 frames to interpolate between n-1 to n+2 frames. last().xdr.cubicInterpolation = True.

The average window button activates averaging all the frames between the current frame n and the n+WindowSize frames.

Note that smoothing and averaging should be fast because it’s done using C# Burst compiler, multi-threaded and SIMD accelerated computation.


Effects (desktop)

Currently, UnityMol has 3 effects you can activate in desktop mode:

Related functions are

enableDepthCueing()
disableDepthCueing()
setDepthCueingStart(0.5)
setDepthCueingDensity(0.1)

Related functions are

enableDOF()
disableDOF()
setDOFAperture(0.1)
setDOFFocalLength(0.1)
setDOFFocusDistance(0.1)

Note: when the DOF effect is activated, clicking on a molecule does not trigger the selection but changes the DOF focus distance.

Related functions are

enableOutline()
disableOutline()
setOutlineThickness(10.0)

Aligning 2 proteins

UnityMol uses CEAlign from here, an algorithm that performs well for low sequence similarity and still fast. It only uses alpha carbons to align the second argument (mobile) of the function cealign on the first argument of the function (target).

As an example, load 2 proteins and display them as cartoon:

s1 = fetch("3eam", showDefaultRep=False)
s2 = fetch("3ei0", showDefaultRep=False)
show("c")
colorSelection(s1.ToSelectionName(), "c", Color.red)
colorSelection(s2.ToSelectionName(), "c", Color.blue)

You should have something like this:

Clicking on “Run CEAlign” from the Utils menu applies CEAlign on the 2 lastly loaded molecules. This is equivalent to cealign(s1.ToSelectionName(), s2.ToSelectionName()).


Bounding boxes

You can show the bounding box of the loaded molecule by doing showBoundingBox("structureName") / hideBoundingBox("structureName").


Overwrite bonding information (PSF / TOP / XML)

PSF

You can load bounding information from a PSF file (NAMD protein structure file)

loadPSFTopology("structureName", "mypathToPSFfile.psf")

TOP

Similarly, you can load a TOP file (Gromacs topology file) to overwrite bounding information and update all representations:

loadTOPTopology("structureName", "mypathToTOPfile.top")

XML

UnityMol provides a simple way to load covalent and non-covalent bonds using a XML format:

<Bonds>
<Bond from="0" to="1" order="2.0" type="covalent"/>
</Bonds>

This links the first atom of the loaded molecule in the order of the loaded file to the second one by a double covalent bond.

Possible bond types are: covalent or db_geom, hbond or h-bond or hbond_weak, halogen, ionic, aromatic, hydrophobic, carbonyl.

loadBondsXML("structureName", "pathToXMLFile.xml")
overrideBondsWithXML("structureName")
unloadCustomBonds("structureName", modelId)
Restoring UnityMol computed topology

After loading a topology from a PSF/TOP/XML file, you can restore the bonds computed by UnityMol at load time by doing:

restoreBonds("structureName")

Secondary structure assignation

When loading a protein with load() or fetch() the default behaviour is to use the secondary structure information from the file and use DSSP algorithm when there is none. You can force DSSP to be run: fetch("1kx2", forceDSSP=True).

You can run DSSP on a loaded molecule by doing: switchSSAssignmentMethod("structureName", forceDSSP=True).

Annotations

There are several types of annotation in UnityMol to add labels, objects, lines, measurements to atoms. To add a transparent sphere around an atom: annotateAtom("structureName", atomId) To add a transparent sphere not attached to an atom, use annotateSphere(worldP=Vector3(0,0,0), scale=1.0)

You can also add some label to an atom: annotateAtomText("structureName", atomId, "My text"), or not attached to an atom: annotateWorldText(Vector3(0,0,0), 1.0, "My text", Color.white). To add text in 2D, you can use annotate2DText(screenP=Vector2(0.5, 0.5), scale=1.0, text="My text", textCol=Color.white) where the screen position is defined by (0,0) = bottom-left and (1,1) = top-right.

To add a line: annotateLine("structureName", atomId, "structureName2", atomId2) and not attached to an atom: annotateWorldLine(Vector3(0,0,0), Vector3(3,0,0), 1.0, Color.white).

Measurements

Measuring is using annotations to display lines and text on atoms: In desktop mode, press “M” and click on atoms to compute a distance/angle/torsion angle based on UnityMolMain.measureMode that can be changed using the command setMeasureMode(mode)where mode is 0 = distance, 1 = angle, 2 = torsion angle. Clicking on the “Measurement mode” button is calling setMeasureMode() function.

In VR, pressing the touchpad button while aiming the target atom should trigger measurements.

You can also play a sonar sound at a position to localize an atom or an object using the playSoundAtPosition(Vector3(10,0,0)) command.

Interactive Molecular Dynamics (IMD)

Connection to a running simulation using the IMD protocol is done via the IMD menu. You can also call connectIMD("structureName", "127.0.0.1", 8888) for a simulation running on the localhost on the 8888 port. Disconnection using the console: disconnectIMD("structureName").

By default, UnityMol uses the last loaded molecule when clicking on IMD connect button.

During IMD, you can grab an atom or several atoms by click & dragging the mouse in desktop or the controller in VR.

The IMD protocol is implemented using MDDriver since UnityMol 1.1.2.

Docking mode

UnityMol team collaborated with Levitt’s lab at Stanford University to build a docking mode in UnityMol, available in VR. It uses the AMBER forcefield to interactively compute the potential energy of the system. For more information please read this page.

Export to OBJ/FBX

One can export the current representations of a structure using one of these functions: exportRepsToOBJFile("structureName", "outputpath.obj") or exportRepsToFBXFile("structureName", "outputpath.fbx").

The FBX format file is a binary file format that is lighter than the OBJ text file format.

Startup commands

You can directly load a molecular file or a command file (previously saved from UnityMol or a custom script) when launching UnityMol from a terminal:

$> ./UnityMol -i /path/to/UMolState.py
$> ./UnityMol -i /path/to/1kx2.pdb /path/to/1bl8.pdb /path/to/1bl8_traj.xtc

To fetch a PDB when starting UnityMol you can do:

$> ./UnityMol -i 3eam

You can also set the directory to easily load local files with

$> ./UnityMol -d /path/to/folder

More information

If you need help or have any question regarding UnityMol and it’s usage, please send an email to unitymol@gmail.com. We are also active on Twitter: @UnityMol