Skip to content

Commit

Permalink
Add view_structures tutorial.
Browse files Browse the repository at this point in the history
  • Loading branch information
mgt16-LANL committed Jan 19, 2024
1 parent 55fbe41 commit aca6b39
Showing 1 changed file with 367 additions and 0 deletions.
367 changes: 367 additions & 0 deletions documentation/tutorials/12-Using_View_Structures.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,367 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 12 - Using View Structures:\n",
"\n",
"\n",
"### In this tutorial we will walk through many examples of how and what to use view structures for, and is meant as a hightlight of this function's ability.\n",
"\n",
"If you do not see a potential capability please let the developers know of your desire on github!!\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from architector import (view_structures,\n",
" build_complex,\n",
" convert_io_molecule)\n",
"from architector.io_calc import CalcExecutor # Run XTB calculations\n",
"from architector.io_samplers import random_sampler # Create distortions\n",
"from architector.vibrations_free_energy import vibration_analysis # Vibrational analysis to get normal modes\n",
"import architector.arch_context_manage as arch_context_manage # Temporary directory generation\n",
"from ase.vibrations import Vibrations # ASE implemenation of vibrational analysis\n",
"import numpy as np "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Even before running architector, view_structures can be used to visualize SMILES strings!\n",
"# In the background, openbabel is used to build these in 3D\n",
"view_structures(['C','CN','COC','CC=CC'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# To start from Architector, let's build complexes to visualize\n",
"inp = {'core':{'metal':'Fe','coreCN':6},\n",
" 'ligands':['bipy']*2+['chloride']+['water'],\n",
" 'parameters':{'skip_duplicate_tests':True,\n",
" 'assemble_method':'UFF',\n",
" 'full_method':'UFF',\n",
" 'relax':True}}\n",
"out = build_complex(inp)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# At it's base, view structures can be called on any number of types of structures.\n",
"# On Architector output dictionaries (e.g. out) it will pull out the mol2string fields to visualize.\n",
"# These are sorted by energy by default\n",
"view_structures(out)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# You can play with the size/shape of viewer grids:\n",
"view_structures(out,\n",
" columns=2, # Check the number of columns the viewer will use.\n",
" w=400, # Change the size of each viewer width in pixels. Default is 200\n",
" h=400 # Change the size of each viewer height in pixels. Default is 200\n",
" )\n",
"# This will thus make a 2X2 grid with larger versions of the molecules viewed."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Now, we will pull out just the mol2strings to highlight other view_structures functionality\n",
"mol_list = [val['mol2string'] for key,val in out.items()]\n",
"energies = [val['energy'] for key,val in out.items()] # Pull out the energies\n",
"energy_labels = ['{0:.2f}'.format(x) for x in (np.array(energies)-min(energies))] # Format and make the energies relative to minimum energy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# We can now add the energies of the structures as labels.\n",
"view_structures(mol_list,\n",
" labels=energy_labels # Add labels to the centroid of the molecules with the relative energies\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# You can also add arbitrary strings or numbers as labels\n",
"view_structures(mol_list,\n",
" labels=np.arange(len(mol_list)) # Add labels corresponding to the indices of the structures\n",
" )\n",
"view_structures(mol_list,\n",
" labels=['zero','one','two',\n",
" 'three','four','five'][:len(mol_list)] # Add labels up to the number of structures produced\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Interatomic distances can also be visualized\n",
"view_structures(mol_list,\n",
" vis_distances=True)\n",
"# For much more parameters on how to edit and tweak visualization of \n",
"# interatomic distances please see tutorial 11-Distance_Analysis.ipynb!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Similar to labels, you can request to label the indices in each structure.\n",
"view_structures(mol_list,\n",
" w=400, # Make the viewer larger\n",
" h=400, # Make the viewer larger\n",
" columns=2, # Switch to two columns\n",
" labelinds=True, # Label the indices of the atoms in the molecule\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# For simplicity, we can select a single structure to view the indices of the atoms in the molecule\n",
"mol = convert_io_molecule(mol_list[1])\n",
"# Similar to labels, you can pass a list of values or strings to visualize on top of the indices.\n",
"view_structures(mol,\n",
" w=400, # Make the viewer larger\n",
" h=400, # Make the viewer larger\n",
" labelinds=(np.arange(len(mol.ase_atoms))/10).tolist(), # Label the indices of the atoms in the molecule\n",
" )\n",
"# Note that this is useful for visualizing charges\n",
"view_structures(mol,\n",
" w=400, # Make the viewer larger\n",
" h=400, # Make the viewer larger\n",
" labelinds=mol.ase_atoms.get_chemical_symbols(), # Add chemical symbols\n",
" )\n",
"labelinds = list(map(chr, range(97, 123))) * 3\n",
"view_structures(mol,\n",
" w=400, # Make the viewer larger\n",
" h=400, # Make the viewer larger\n",
" labelinds=labelinds[:len(mol.ase_atoms)], # Add arbitrary letters to each atom\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Note, this can all be done for lists of structures as well!!!\n",
"labelinds = list(map(chr, range(97, 123))) * 3\n",
"view_structures(mol_list,\n",
" labelinds=[labelinds[:len(mol.ase_atoms)]]*len(mol_list), # Add arbitrary letters to each atom for each structure in list\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Now, we can also play with the parameters for the visualization itself.\n",
"view_structures(mol,\n",
" representation='stick', # Switch to stick representation\n",
" stick_scale=0.5, # Make the sticks larger\n",
" )\n",
"view_structures(mol,\n",
" representation='sphere' # Switch to sphere representation\n",
" )\n",
"view_structures(mol,\n",
" sphere_scale=0.5, # Increase sphere scales\n",
" metal_scale=1.3, # Increase metal sphere scale even more.\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Now, we can distort and relax a structure with XTB with in-built routines:\n",
"distortion,_,_ = random_sampler(mol,\n",
" n=1, # Produce one distortion\n",
" max_rmsd=0.2 # Make sure it's not too different \n",
" ) \n",
"distortion = distortion[0]\n",
"view_structures([mol,distortion],\n",
" labels=['UFF Minima','Distorted'],\n",
" columns=2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Now, we can relax the distortion\n",
"xtb_relaxed = CalcExecutor(mol,\n",
" method='GFN2-xTB',\n",
" relax=True,\n",
" save_trajectories=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Now we can visulaze both the distortion and the relaxed structures\n",
"view_structures([distortion,xtb_relaxed.mol],\n",
" labels=['Distorted','XTB Relaxed'],\n",
" columns=2\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Further, we can animate the relaxation trajectory! \n",
"view_structures(xtb_relaxed.trajectory,\n",
" w=400,\n",
" h=400,\n",
" trajectory=True # Treat as a trajectory for animation\n",
" )\n",
"# Note that anything that is a list of structures that architector can read (ase atoms, xyz, mol2 ...)\n",
"# Can be treated as a trajectory"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Further, we can animate the relaxation trajectory! \n",
"view_structures(xtb_relaxed.trajectory,\n",
" w=400,\n",
" h=400,\n",
" interval=400, # Slow down the trajectory animation\n",
" trajectory=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Note that this block takes around 1 minute on an M2Max Macbook Pro.\n",
"calced = CalcExecutor(xtb_relaxed.mol,\n",
" method='GFN2-xTB') # Re-run single point to get vibrations\n",
"with arch_context_manage.make_temp_directory() as _:\n",
" vib_analysis = Vibrations(calced.mol.ase_atoms) # Run vibrational analysis using ASE\n",
" vib_analysis.run()\n",
" data = vib_analysis.get_vibrations() # Get the vibrations\n",
" hess = data.get_hessian_2d() # Get the hessian \n",
"# Calculate the normal modes, force constnaces, and vibrational energies.\n",
"vib_energies, modes, fconstants, _ , frequencies = vibration_analysis(calced.mol.ase_atoms,\n",
" hess)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# With the vibrational modes, we can now visualize mode vibrations\n",
"view_structures(calced.mol,\n",
" modes=[modes[7]] # Visualize just one mode (non-zero modes start a 7)\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# We can also visualize more than one mode\n",
"view_structures([calced.mol]*8,\n",
" modes=modes[30:(30+8)], # Visualize First 8 modes\n",
" labels=frequencies[30:(30+8)] # Add labels corresponding to the frequencies modes (cm^-1)\n",
" )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Conclusions to using View Structures\n",
"\n",
"In this tutorial we walked through several examples highlighting view structures capabilites.\n",
"\n",
"Although all of these examples were performed using Architector-generated structures,\n",
"\n",
"All these capabilities can also be done with local files or paths pointing to structure files including xyz, mol2 ..."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit aca6b39

Please sign in to comment.