In [ ]:
# This cell sets up both the python and notebook environments
%matplotlib inline
import moldesign as mdt # import the buckyball package
from moldesign import units as u # import the buckyball unit system
In [ ]:
my_first_molecule = mdt.from_name('morphine')
my_first_molecule.draw()
You've just created your first molecule in buckyball - the bb.from_name
method can translate many common chemical names, as well as IUPAC nomenclature, into 2D and 3D chemical structures.
If morphine is a little intimdating, you can try making caffeine, or even just water, by editing the code in the above cell. You can edit any code in this notebook at any time, and press Shift + Return
to execute the new commands.
Let's take a look at your Molecule
's attributes. Try using Jupyter's live autocompletion - typing my_first_molecule.[tab]
, for instance, will show you a list of the object's attributes.
In [ ]:
my_first_molecule
Every chemical system in buckyball is called a Molecule
. These objects store information about atoms, chemical bonds, 3D positions, and chemical properties. A Molecule
object is more than just a data store, though - they also have methods for simulating, modeling, and visualizing this information.
A list of the molecule's atoms are stored at my_first_molecule.atoms
. Let's print out some custom information about the first five atoms:
In [ ]:
print 'This molecule has %d atoms' % my_first_molecule.num_atoms
for atom in my_first_molecule.atoms[:5]:
print 'Atom {atom} (atomic number {atom.atnum}) weighs {atom.mass}, and ' \
'is bonded to {atom.num_bonds} other atoms.'.format(atom=atom)
In [ ]:
my_first_molecule.atoms[-1]
Sometimes, a 3D structure needs to be fixed - perhaps the wrong rotamer was generated, or someone gave you a non-planar geometry of a planar molecule.
For instance, the OpenBabel SMILES converter will generate a gauche-conformation alkane, when we really want an anti conformation. Let's use the GeometryBuilder to fix it - click on the central dihedral bond, and adjust the angle to 180º, either with the slider or by typing "180".
In [ ]:
mol = mdt.from_smiles('CCCC')
mdt.ui.GeometryBuilder(mol)
Of course, you'll probably want to import and export your own molecular structures. Buckyball can read and write molecules from a variety of 3D formats, including pdb
, sdf
, mol2
, cif
, and xyz
.
Let's start by reading in a file that was downloaded from the PDB database (you can also use bb.from_pdb(3AID)
to download it directly from the PDB site). We can get some quick information about the molecule in the file just by its name on the last line of the cell.
In [ ]:
hivprotease = mdt.read('data/3AID.pdb')
hivprotease
This is a crystal structure of a protein (HIV-1 protease) that's bound to a small organic drug molecule (that's the single unknown residue type). In addition to the protein and drug, there are also several water molecules hanging around the structure.
In [ ]:
hivprotease.draw()
Let's pull the drug molecule out of the structure and save it to disk. First, click on one of the atoms in the drug. You'll see that it's Residue ARQ401
in Chain A
. We can grab this residue by going into the molecule's secondary structure:
In [ ]:
drugresidue = hivprotease.chains['A'].residues['ARQ401']
In [ ]:
drug = mdt.Molecule(drugresidue)
drug.draw3d()
Now, we'll write it to disk:
In [ ]:
drug.write(filename='/tmp/drugmol.xyz')
In [ ]:
!cat /tmp/drugmol.xyz
As a quick first example, let's take a look at a quantum mechanical model of benzene.
This time, we'll construct the molecule in yet another way - by using a SMILES string.
In [ ]:
mol = mdt.from_smiles('C1=CC=CC=C1')
mol.draw()
Next, we associate the quantum mechanical model with the molecule, and run a calculation:
In [ ]:
mol.set_energy_model(mdt.models.PySCFPotential(theory='rhf',basis='sto-3g'))
mol.calculate()
There's a bunch of data here, which we'll dive into in other notebooks. For now, we can visualize the results of the calculation:
In [ ]:
mol.draw_orbitals()
You can visualize two different kinds of orbitals here: the canonical molecular orbitals, often just referred to as "molecular orbitals" (MOs); and atomic orbitals, which were combined to create the MOs.
You can access and create molecule visualizations in the notebook as well.
First, let's draw some more information into our visualization. We'll draw all the protein's potential hydrogen bond donors (basically Oxygens and Nitrogens) as spheres, and highlight those close to the ligand.
In [ ]:
viewer = hivprotease.draw3d()
hdonors = [atom for atom in hivprotease.atoms
if atom.elem in ('O','N') and atom.residue.type == 'protein']
viewer.add_style(style='vdw', atoms=hdonors, radius=0.5)
viewer.highlight_atoms(atoms=[a for a in hdonors if a.distance(drugresidue) <= 4.0*u.angstrom])
viewer
The cell below constructs a quick visualization of the HIV drug's contacts with the surrounding protein residues, with 2D rendering, a 3D rendering, and an inspector that provides information about atoms that the user clicks on:
In [ ]:
contact_view = bb.viewer.make_contact_view(drugresidue,view_radius=3.5*u.angstrom,
contact_radius=2.25*u.angstrom,
width=600,height=400)
geom_view = bb.viewer.GeometryViewer(hivprotease, width=600,height=300)
geom_view.cartoon(opacity=0.7)
geom_view.licorice(atoms=drugresidue,radius=0.5)
for residue,color in contact_view.colored_residues.iteritems():
geom_view.licorice(atoms=residue,color=color)
# We use the ipywidgets package to arrange the three UI elements:
import ipywidgets as ipy
viewer_group = ipy.VBox([geom_view,contact_view])
selector = bb.ui.SelectionGroup([ipy.HBox([viewer_group,bb.ui.AtomInspector()])])
selector