Optimization and normal modes#
In this section we will see how to visualize geometry optimization trajectories, as well as molecular vibration modes using py3Dmol.
Geometry optimization#
import veloxchem as vlx
import py3Dmol as p3d
from matplotlib import pyplot as plt
import numpy as np
import ipywidgets
import h5py
Let’s assume we have run the geometry optimization and saved all the steps in xyz
format in a file. To animate the optimization trajectory we first need a routine which reads the configurations from file.
def read_xyz_file(file_name):
"""Reads all the configurations from an xyz geometry optimization file."""
xyz_file = open(file_name, "r")
data = xyz_file.read()
xyz_file.close()
xyz_file = open(file_name, "r")
i = 0
steps = []
energies = []
for line in xyz_file:
if "Energy" in line:
steps.append(i)
i += 1
parts = line.split()
energy = float(parts[-1])
energies.append(energy)
xyz_file.close()
return data, steps, energies
Using this routine, we can plot the energies during optimization, as well as animate the trajectory.
xyz_file_name = '../../data/md/kahweol_optim.xyz'
xyz_data, steps, energies = read_xyz_file(xyz_file_name)
# Plot the energies
plt.figure(figsize=(7,4))
plt.plot(steps, energies,'o--')
plt.xlabel('Iteration')
plt.ylabel('Energy (H)')
plt.title("Kahweol XTB optimization")
plt.tight_layout(); plt.show()
# and animate the optimization
viewer = p3d.view(width=600, height=300)
viewer.addModelsAsFrames(xyz_data)
viewer.animate({"loop": "forward"})
viewer.setViewStyle({"style": "outline", "width": 0.05})
viewer.setStyle({"stick": {}, "sphere": {"scale": 0.25}})
viewer.show()

3Dmol.js failed to load for some reason. Please check your browser console for error messages.
If instead we would like to see each configuration individually, we can create an interactive widget with a slider. As in the previous section, we need a routine which reads an individual configuration at a time and returns the corresponding py3Dmol viewer.
def read_xyz_index(file_name, index=0):
"""Reads one configuration defined by its index from the xyz optimization file."""
xyz_file = open(file_name, "r")
current_index = 0
data = ""
# Read the number of atoms from the first line
line = xyz_file.readline()
natm = line.split()[0]
data += line
for line in xyz_file:
if index == current_index:
data += line
if 'Energy' in line:
parts = line.split()
energy = float(parts[-1])
if natm in line:
parts = line.split()
if len(parts) == 1:
if index == current_index:
break
current_index += 1
xyz_file.close()
return data, energy
def return_viewer(file_name, step=0):
xyz_data_i, energy_i = read_xyz_index(file_name, step)
# Uncomment if you would also like to see the energy plot
# or comment out if you would like to skip this.
plt.figure(figsize=(7,4))
plt.plot(steps, energies, 'o--')
plt.plot(step, energy_i, 'o', markersize=15)
plt.xlabel('Iteration')
plt.ylabel('Energy (H)')
plt.title("Kahweol XTB optimization")
plt.tight_layout(); plt.show()
viewer = p3d.view(width=600, height=300)
viewer.addModel(xyz_data_i)
viewer.setViewStyle({"style": "outline", "width": 0.05})
viewer.setStyle({"stick": {}, "sphere": {"scale": 0.25}})
viewer.show()
total_steps = steps[-1] # number of configurations in the trajectory file
# Note that the slider only works in a Jupyter notebook.
ipywidgets.interact(return_viewer, file_name=xyz_file_name,
step=ipywidgets.IntSlider(min=0, max=total_steps, step=1, value=3))
<function __main__.return_viewer(file_name, step=0)>
Vibrational normal modes#
Now let’s see how to animate and visualize vibrational normal modes. For this, we will need to determine the molecular Hessian and perform a vibrational analysis.
xtb_drv = vlx.XtbDriver()
xtb_vibanalysis_drv = vlx.VibrationalAnalysis(xtb_drv)
In order to perform a vibrational analysis we need a Molecule
object which stores the optimized geometry. To create the Molecule
object we will read the last geometry from the xyz
file we used in the previous subsection.
# read the last configuration from file
kahweol_xyz, opt_energy = read_xyz_index(file_name=xyz_file_name, index=total_steps)
# create the Mlecul object
xtb_opt_kahweol = vlx.Molecule.read_xyz_string(kahweol_xyz)
# perform vibrational analysis -- diagonalize Hessian, extract frequencies and normal modes
# and calculate IR intensities.
xtb_vibanalysis_drv.compute(xtb_opt_kahweol)
Show code cell output
Vibrational Analysis Driver
=============================
The following will be computed:
- Vibrational frequencies and normal modes
- Force constants
- IR intensities
XTB Hessian Driver
====================
Hessian Type : Numerical
Numerical Method : Symmetric Difference Quotient
Finite Difference Step Size : 0.001 a.u.
*** Time spent in Hessian calculation: 49.65 sec ***
Free Energy Analysis
======================
Note: Rotational symmetry is set to 1 regardless of true symmetry
No Imaginary Frequencies
Free energy contributions calculated at @ 298.15 K:
Zero-point vibrational energy: 263.1952 kcal/mol
H (Trans + Rot + Vib = Tot): 1.4812 + 0.8887 + 10.5627 = 12.9326 kcal/mol
S (Trans + Rot + Vib = Tot): 43.1588 + 34.2859 + 62.5826 = 140.0273 cal/mol/K
TS (Trans + Rot + Vib = Tot): 12.8678 + 10.2223 + 18.6590 = 41.7491 kcal/mol
Ground State Electronic Energy : E0 = -68.32150638 au ( -42872.3925 kcal/mol)
Free Energy Correction (Harmonic) : ZPVE + [H-TS]_T,R,V = 0.37350618 au ( 234.3787 kcal/mol)
Gibbs Free Energy (Harmonic) : E0 + ZPVE + [H-TS]_T,R,V = -67.94800020 au ( -42638.0139 kcal/mol)
Vibrational Analysis
======================
* Info * The 5 dominant normal modes are printed below.
Vibrational Mode 11
----------------------------------------------------
Harmonic frequency: 209.80 cm**-1
Reduced mass: 1.2481 amu
Force constant: 0.0324 mdyne/A
IR intensity: 210.5900 km/mol
Normal mode:
X Y Z
1 O -0.0089 0.0314 0.0212
2 O 0.0272 -0.0105 -0.0492
3 O -0.0321 0.0119 0.0044
4 C 0.0009 0.0003 -0.0124
5 C -0.0003 0.0028 0.0096
6 C 0.0178 0.0097 -0.0062
7 C 0.0022 -0.0100 -0.0128
8 C 0.0094 0.0227 -0.0176
9 C -0.0083 -0.0096 0.0137
10 C 0.0183 0.0190 -0.0036
11 C -0.0074 -0.0026 -0.0175
12 C 0.0209 0.0126 0.0245
13 C 0.0282 0.0055 0.0235
14 C -0.0178 -0.0138 0.0120
15 C -0.0223 -0.0116 0.0121
16 C 0.0082 0.0034 0.0106
17 C 0.0146 -0.0184 -0.0440
18 C -0.0253 -0.0106 -0.0019
19 C -0.0179 -0.0086 0.0007
20 C -0.0279 -0.0045 -0.0037
21 C -0.0310 -0.0008 0.0067
22 C -0.0072 -0.0013 -0.0130
23 C -0.0161 0.0119 -0.0089
24 H 0.0030 0.0160 0.0104
25 H 0.0153 0.0191 -0.0039
26 H 0.0055 -0.0287 -0.0100
27 H -0.0024 -0.0110 -0.0218
28 H 0.0160 0.0471 -0.0001
29 H 0.0002 0.0347 -0.0503
30 H 0.0121 0.0110 -0.0153
31 H -0.0210 -0.0028 -0.0398
32 H 0.0174 0.0343 0.0329
33 H 0.0349 -0.0000 0.0346
34 H 0.0314 -0.0170 0.0255
35 H 0.0302 0.0083 0.0348
36 H -0.0242 -0.0146 0.0121
37 H -0.0437 -0.0028 0.0102
38 H -0.0182 -0.0142 0.0290
39 H 0.0282 -0.0944 0.0073
40 H 0.0942 0.0693 -0.0065
41 H -0.0776 0.0476 0.0285
42 H 0.0060 -0.0934 -0.0140
43 H -0.0057 -0.0188 -0.1102
44 H -0.0331 -0.0228 -0.0157
45 H 0.5898 -0.2695 0.4526
46 H -0.0271 -0.0107 -0.0157
47 H 0.0057 -0.0047 -0.0237
48 H 0.3195 -0.1763 0.3724
49 H -0.0126 0.0211 -0.0134
Vibrational Mode 119
----------------------------------------------------
Harmonic frequency: 2925.13 cm**-1
Reduced mass: 1.0756 amu
Force constant: 5.4222 mdyne/A
IR intensity: 75.6487 km/mol
Normal mode:
X Y Z
1 O 0.0002 0.0002 -0.0003
2 O 0.0001 0.0001 -0.0002
3 O -0.0000 -0.0000 -0.0000
4 C 0.0001 0.0003 -0.0003
5 C -0.0002 0.0000 0.0016
6 C -0.0475 -0.0027 0.0619
7 C 0.0004 0.0036 0.0003
8 C 0.0002 0.0005 -0.0008
9 C 0.0001 0.0000 0.0001
10 C -0.0018 -0.0003 0.0019
11 C 0.0001 -0.0001 -0.0010
12 C -0.0001 0.0000 -0.0012
13 C -0.0012 -0.0035 -0.0021
14 C -0.0000 0.0000 0.0002
15 C -0.0001 0.0001 0.0001
16 C 0.0000 -0.0000 0.0000
17 C 0.0007 0.0012 0.0020
18 C -0.0000 0.0000 -0.0000
19 C 0.0000 -0.0000 0.0000
20 C -0.0000 -0.0000 0.0000
21 C 0.0000 0.0000 0.0000
22 C -0.0000 0.0000 -0.0000
23 C -0.0000 0.0000 -0.0000
24 H 0.0028 0.0005 -0.0213
25 H 0.6034 0.0385 -0.7855
26 H 0.0078 0.0064 0.0083
27 H -0.0224 -0.0533 0.0080
28 H -0.0012 -0.0066 0.0093
29 H -0.0003 0.0011 0.0002
30 H -0.0020 0.0006 0.0135
31 H 0.0002 -0.0003 -0.0006
32 H 0.0062 -0.0015 0.0081
33 H -0.0022 -0.0019 0.0001
34 H 0.0328 0.0055 0.0516
35 H -0.0362 0.0306 -0.0059
36 H 0.0001 -0.0001 -0.0026
37 H 0.0000 0.0000 -0.0007
38 H 0.0013 -0.0019 -0.0007
39 H -0.0006 -0.0001 -0.0002
40 H -0.0001 -0.0002 0.0004
41 H -0.0003 0.0005 0.0001
42 H -0.0079 -0.0106 -0.0241
43 H -0.0025 -0.0037 0.0019
44 H 0.0004 -0.0002 0.0001
45 H 0.0047 0.0029 0.0002
46 H 0.0003 0.0006 -0.0002
47 H -0.0000 -0.0002 0.0000
48 H 0.0004 -0.0003 0.0010
49 H 0.0002 -0.0001 0.0001
Vibrational Mode 125
----------------------------------------------------
Harmonic frequency: 2979.68 cm**-1
Reduced mass: 1.0740 amu
Force constant: 5.6181 mdyne/A
IR intensity: 86.4818 km/mol
Normal mode:
X Y Z
1 O 0.0000 -0.0002 0.0002
2 O 0.0000 -0.0000 0.0000
3 O -0.0000 -0.0000 -0.0000
4 C 0.0012 0.0026 -0.0004
5 C -0.0001 -0.0002 0.0013
6 C 0.0030 0.0016 -0.0024
7 C 0.0241 0.0565 -0.0074
8 C -0.0018 -0.0090 0.0001
9 C 0.0001 -0.0000 -0.0000
10 C 0.0001 0.0000 -0.0002
11 C 0.0135 0.0283 0.0026
12 C 0.0123 0.0039 0.0123
13 C 0.0108 -0.0057 0.0070
14 C -0.0002 0.0004 0.0008
15 C -0.0109 0.0162 0.0133
16 C 0.0013 0.0003 -0.0012
17 C 0.0005 0.0008 -0.0001
18 C 0.0002 -0.0003 0.0001
19 C 0.0000 0.0001 -0.0000
20 C 0.0000 0.0001 -0.0001
21 C -0.0000 -0.0001 0.0000
22 C -0.0001 -0.0002 0.0000
23 C 0.0000 -0.0000 0.0000
24 H 0.0022 0.0012 -0.0160
25 H -0.0266 -0.0019 0.0331
26 H -0.0124 0.0209 -0.0304
27 H -0.2875 -0.7254 0.1240
28 H 0.0019 0.0153 -0.0284
29 H 0.0189 0.0941 0.0261
30 H 0.0289 0.0084 -0.1649
31 H -0.2033 -0.3600 0.1353
32 H -0.0930 0.0342 -0.1352
33 H -0.0573 -0.0852 -0.0140
34 H -0.0445 -0.0173 -0.0782
35 H -0.0911 0.0885 -0.0054
36 H -0.0003 -0.0004 -0.0040
37 H 0.0053 0.0071 -0.0935
38 H 0.1393 -0.2018 -0.0680
39 H 0.0019 0.0002 -0.0006
40 H -0.0101 0.0136 0.0032
41 H -0.0063 -0.0170 0.0100
42 H 0.0003 0.0004 -0.0001
43 H -0.0049 -0.0092 0.0011
44 H -0.0015 0.0023 -0.0011
45 H -0.0008 -0.0001 -0.0008
46 H -0.0007 -0.0014 0.0006
47 H 0.0004 0.0026 -0.0006
48 H -0.0003 0.0000 -0.0001
49 H -0.0000 -0.0001 0.0000
Vibrational Mode 128
----------------------------------------------------
Harmonic frequency: 2999.40 cm**-1
Reduced mass: 1.0753 amu
Force constant: 5.6994 mdyne/A
IR intensity: 72.5351 km/mol
Normal mode:
X Y Z
1 O -0.0001 0.0003 0.0002
2 O 0.0001 0.0001 -0.0001
3 O 0.0000 0.0000 0.0000
4 C -0.0006 -0.0018 0.0006
5 C -0.0000 -0.0011 0.0028
6 C 0.0001 -0.0004 0.0001
7 C -0.0027 -0.0065 0.0010
8 C -0.0122 -0.0609 0.0157
9 C -0.0001 -0.0002 0.0000
10 C -0.0000 -0.0018 0.0002
11 C -0.0019 -0.0039 -0.0002
12 C -0.0040 -0.0370 0.0181
13 C 0.0072 -0.0107 -0.0023
14 C 0.0001 0.0000 -0.0000
15 C 0.0002 0.0000 -0.0035
16 C -0.0010 0.0004 -0.0001
17 C 0.0022 0.0041 -0.0009
18 C -0.0009 0.0011 -0.0004
19 C -0.0000 -0.0000 -0.0000
20 C -0.0000 -0.0001 0.0000
21 C -0.0001 -0.0000 -0.0000
22 C -0.0000 0.0000 -0.0000
23 C -0.0000 0.0000 -0.0000
24 H 0.0039 0.0009 -0.0365
25 H 0.0011 -0.0003 -0.0018
26 H 0.0014 -0.0018 0.0040
27 H 0.0330 0.0836 -0.0156
28 H 0.0310 0.2286 -0.3558
29 H 0.1182 0.5297 0.1644
30 H -0.0041 -0.0013 0.0219
31 H 0.0287 0.0534 -0.0195
32 H -0.2449 0.0602 -0.3385
33 H 0.2999 0.3955 0.1081
34 H 0.0357 0.0043 0.0535
35 H -0.1315 0.1198 -0.0130
36 H 0.0002 -0.0000 -0.0008
37 H -0.0048 0.0006 0.0457
38 H 0.0012 -0.0014 -0.0025
39 H 0.0095 0.0024 0.0024
40 H 0.0037 -0.0049 -0.0011
41 H -0.0013 -0.0010 0.0004
42 H 0.0018 0.0036 0.0020
43 H -0.0291 -0.0517 0.0065
44 H 0.0087 -0.0106 0.0061
45 H 0.0018 -0.0010 -0.0023
46 H 0.0008 0.0015 -0.0006
47 H -0.0000 -0.0001 0.0000
48 H 0.0003 -0.0003 -0.0001
49 H -0.0001 0.0001 -0.0000
Vibrational Mode 130
----------------------------------------------------
Harmonic frequency: 3009.03 cm**-1
Reduced mass: 1.0598 amu
Force constant: 5.6535 mdyne/A
IR intensity: 69.9220 km/mol
Normal mode:
X Y Z
1 O 0.0001 -0.0000 -0.0002
2 O 0.0000 0.0000 -0.0001
3 O 0.0000 0.0001 -0.0000
4 C -0.0001 -0.0000 0.0013
5 C -0.0001 -0.0002 0.0014
6 C -0.0004 -0.0001 0.0004
7 C -0.0022 -0.0016 -0.0020
8 C 0.0021 0.0021 0.0350
9 C -0.0000 0.0003 0.0002
10 C -0.0000 0.0001 0.0009
11 C -0.0024 -0.0030 0.0085
12 C 0.0018 -0.0002 0.0025
13 C 0.0005 0.0008 0.0018
14 C -0.0001 -0.0006 0.0027
15 C 0.0024 -0.0119 0.0563
16 C 0.0021 0.0043 -0.0022
17 C 0.0014 0.0024 0.0004
18 C -0.0001 0.0001 -0.0001
19 C 0.0001 -0.0001 0.0000
20 C 0.0000 0.0001 -0.0001
21 C -0.0000 -0.0001 0.0000
22 C 0.0001 0.0004 -0.0001
23 C 0.0000 -0.0001 0.0000
24 H 0.0024 0.0020 -0.0190
25 H 0.0050 0.0004 -0.0068
26 H 0.0236 0.0092 0.0261
27 H 0.0047 0.0126 -0.0035
28 H 0.0397 0.2731 -0.3656
29 H -0.0649 -0.2972 -0.0659
30 H 0.0119 -0.0043 -0.0774
31 H 0.0227 0.0392 -0.0113
32 H -0.0214 0.0074 -0.0314
33 H -0.0022 -0.0044 0.0003
34 H -0.0135 -0.0033 -0.0218
35 H 0.0072 -0.0062 0.0014
36 H -0.0009 -0.0012 -0.0168
37 H 0.0807 -0.0135 -0.7877
38 H -0.1099 0.1555 0.0869
39 H -0.0089 0.0000 -0.0035
40 H 0.0017 0.0006 -0.0016
41 H -0.0188 -0.0482 0.0304
42 H -0.0036 -0.0024 -0.0099
43 H -0.0146 -0.0265 0.0039
44 H 0.0016 -0.0019 0.0009
45 H -0.0015 0.0001 0.0028
46 H -0.0005 -0.0006 0.0004
47 H -0.0011 -0.0043 0.0012
48 H -0.0000 0.0000 0.0002
49 H -0.0007 0.0004 -0.0002
* Info * Full vibrational analysis results written to: vib-results.out
{'molecule_xyz_string': '49\n\nO -4.444356148300 -1.519231405700 0.133818803000\nO -5.717728473400 0.942316237100 -0.066968962400\nO 5.074944380100 0.621839630700 0.095361864000\nC -1.218663248700 -0.830595956300 -0.247223992800\nC -0.477629871500 0.497184226800 -0.529673918500\nC -2.930011813600 0.109407860600 1.091647841000\nC -1.787420846300 -0.894913983900 1.174595923900\nC -2.515711138500 -0.855946194500 -1.095040548800\nC 0.968464285400 0.594394878100 0.023051359100\nC -3.654907965800 -0.372192923700 -0.180394141400\nC -0.338906858500 -2.036979464400 -0.583399668300\nC -1.380813476500 1.698304225800 -0.180085905800\nC -2.322111192600 1.507002611300 1.012160927000\nC 1.723598180200 -0.686836785300 -0.399658653300\nC 1.033616297100 -1.956732648500 0.075560115900\nC 1.068852139200 0.833440819900 1.537692826600\nC -4.585050097800 0.655858178700 -0.853861880100\nC 1.691896058500 1.770006746900 -0.620577515400\nC 3.162347118000 -0.539762374900 -0.024338881700\nC 3.026560322800 1.832733770700 -0.661355332100\nC 3.761395103300 0.686565534800 -0.201084928000\nC 4.186018037300 -1.411360657400 0.402952793600\nC 5.318365378800 -0.649258410900 0.464736569000\nH -0.335036180700 0.523105135000 -1.619153336000\nH -3.599176954100 0.065966348100 1.957690684700\nH -1.080856355100 -0.645807578400 1.956928694700\nH -2.177294049000 -1.897906384700 1.358785220600\nH -2.433801681300 -0.246547664800 -1.993148048300\nH -2.750703334400 -1.876555715600 -1.397466956800\nH -0.203126601800 -2.084320493000 -1.667436130400\nH -0.851890375400 -2.949981497800 -0.273589578900\nH -1.983411213200 1.924016483600 -1.061330676900\nH -0.767945077200 2.580213930300 0.010339706900\nH -1.779556090200 1.670505612800 1.945822615500\nH -3.112392348700 2.258845075600 0.965603116300\nH 1.702548680000 -0.706998814100 -1.502646038800\nH 0.940906440200 -1.969012908100 1.160909209200\nH 1.629806822600 -2.823430346800 -0.216840792700\nH 2.103739193800 1.037127297700 1.803288498700\nH 0.473184324800 1.693615965100 1.827260296200\nH 0.749302119400 -0.028513839400 2.112157924200\nH -4.890341941000 0.251895622800 -1.829136457400\nH -4.081362417900 1.607147612800 -1.012173100000\nH 1.101176933700 2.597977027300 -0.978171475100\nH -4.939036199800 -1.335514044100 0.940761097800\nH 3.561011194900 2.688548100800 -1.042815340900\nH 4.105646417200 -2.452204647200 0.640894394400\nH -6.244800187700 0.136371594000 -0.009353562100\nH 6.323262711400 -0.890385787700 0.749405341100\n',
'gibbs_free_energy': -67.94800020186979,
'free_energy_summary': 'Note: Rotational symmetry is set to 1 regardless of true symmetry\nNo Imaginary Frequencies\n\nFree energy contributions calculated at @ 298.15 K:\nZero-point vibrational energy: 263.1952 kcal/mol\nH (Trans + Rot + Vib = Tot): 1.4812 + 0.8887 + 10.5627 = 12.9326 kcal/mol\nS (Trans + Rot + Vib = Tot): 43.1588 + 34.2859 + 62.5826 = 140.0273 cal/mol/K\nTS (Trans + Rot + Vib = Tot): 12.8678 + 10.2223 + 18.6590 = 41.7491 kcal/mol\n\nGround State Electronic Energy : E0 = -68.32150638 au ( -42872.3925 kcal/mol)\nFree Energy Correction (Harmonic) : ZPVE + [H-TS]_T,R,V = 0.37350618 au ( 234.3787 kcal/mol)\nGibbs Free Energy (Harmonic) : E0 + ZPVE + [H-TS]_T,R,V = -67.94800020 au ( -42638.0139 kcal/mol)\n',
'vib_frequencies': array([ 44.69491154, 50.44903384, 80.29947435, 92.89365775,
134.98222001, 147.48906262, 162.65914603, 190.61575668,
194.86081378, 207.19925985, 209.79987727, 267.88004213,
271.09384492, 271.46569015, 294.5088592 , 301.76536918,
319.20897907, 333.41455327, 357.09474974, 367.61197863,
377.1208492 , 381.4349751 , 416.84618652, 434.14325991,
447.3014811 , 454.30115765, 475.52642382, 506.42510337,
523.94406043, 527.58054624, 561.00887648, 592.24339767,
604.82662224, 628.27145568, 640.70358348, 654.46039492,
685.02746934, 744.40076171, 749.04143664, 778.29940438,
779.33668313, 789.81282251, 819.16360046, 832.40074811,
834.17424022, 857.90521157, 883.70123011, 891.86021845,
893.82617384, 900.72568117, 910.02336017, 931.62611442,
942.76432331, 949.4107064 , 968.35735492, 996.1146707 ,
1000.19976807, 1023.94622975, 1030.89720559, 1043.35231388,
1048.27592678, 1063.15810334, 1066.84912422, 1078.7475574 ,
1085.87519081, 1089.80583704, 1090.05968307, 1113.32149999,
1116.47850361, 1140.79095318, 1144.19734602, 1152.23085206,
1155.30506139, 1167.53985571, 1174.26365956, 1178.94455289,
1188.70551173, 1196.77845034, 1198.38012064, 1216.86293384,
1221.92802594, 1240.31695784, 1242.42438667, 1267.06549427,
1271.30966816, 1278.74839999, 1283.38940574, 1294.95846749,
1301.17398743, 1302.69739414, 1310.24021565, 1322.32159984,
1332.62047329, 1339.90274919, 1342.42778295, 1349.38060307,
1352.3027893 , 1358.76187491, 1359.87979797, 1374.09872415,
1376.6825146 , 1403.84700472, 1446.48635365, 1459.27494874,
1467.691074 , 1475.43822635, 1477.89659204, 1484.78257289,
1493.8301875 , 1496.95043471, 1502.40853062, 1512.89831678,
1515.31361139, 1569.0982833 , 1637.47823068, 2833.71679462,
2884.03523559, 2891.28973896, 2925.13228551, 2954.30131762,
2962.49948579, 2971.2580686 , 2976.74740666, 2977.665718 ,
2979.6788747 , 2986.27239085, 2996.28460882, 2999.40352894,
3007.88118405, 3009.02596924, 3030.18155127, 3036.13696792,
3056.33516591, 3063.95052614, 3076.54096433, 3086.53433179,
3101.10144045, 3166.31380455, 3184.03863237, 3525.83451961,
3530.45858026]),
'normal_modes': array([[ 6.40967664e-03, 4.51307948e-02, -7.77724211e-04, ...,
5.54834022e-02, -8.71926268e-02, -2.19524453e-01],
[-6.88588709e-02, -3.51079246e-03, -7.91298719e-02, ...,
8.47720051e-02, 3.19715200e-02, -2.87039682e-01],
[-9.17341875e-02, 9.03059921e-02, -4.75186031e-02, ...,
-2.05716680e-02, 1.47466437e-01, 1.57913522e-01],
...,
[ 5.34879761e-06, 9.36506294e-06, -4.04009656e-07, ...,
-3.68308212e-01, 8.87747437e-02, -1.04357236e-01],
[ 3.63433089e-03, -1.38132518e-03, -5.73857974e-03, ...,
-1.06213442e-05, 2.43416159e-08, -2.70556687e-06],
[ 3.09677608e-02, -1.20120634e-02, -5.16020077e-02, ...,
8.87143825e-06, 2.08449448e-07, 3.47326637e-06]]),
'reduced_masses': array([4.84811979, 5.08283073, 3.62816346, 4.47364163, 2.76443075,
3.69862136, 4.126267 , 1.983495 , 2.78576617, 3.63192272,
1.24806763, 2.5902338 , 2.88526114, 2.85889748, 3.1301336 ,
2.98863977, 2.5694987 , 2.41903199, 2.81910835, 3.38275498,
2.3420533 , 2.71444909, 3.91175397, 2.44535461, 2.59173438,
2.55922201, 1.41369645, 3.498006 , 3.44645161, 2.83528735,
3.32212265, 4.3267316 , 5.26266523, 3.592449 , 4.49422298,
3.90971551, 3.36850508, 2.64246529, 1.33900107, 2.79557247,
1.90310712, 3.01600046, 2.963243 , 1.4854916 , 2.22420897,
2.13691102, 1.90714285, 1.38652191, 2.44715141, 2.29147926,
2.13059652, 2.20705077, 1.96281121, 1.7154786 , 1.99127087,
2.02184623, 1.83255182, 1.70495097, 2.12673971, 2.02597953,
1.91017114, 1.803213 , 1.75786474, 1.92015404, 1.50101887,
1.9983815 , 3.06659916, 1.9475057 , 1.62413805, 1.38018322,
1.74801463, 1.96503363, 1.59259129, 1.88171472, 1.46248761,
2.41985501, 1.94057425, 1.46786741, 1.56932212, 1.9766162 ,
2.13260856, 2.37858835, 2.06706519, 2.07181221, 1.74111945,
1.35508968, 1.72803607, 1.57442049, 1.41244635, 1.78993158,
1.64645857, 1.30086609, 1.49119368, 1.45387019, 1.76120864,
1.4220872 , 1.95828446, 1.9336672 , 1.38911471, 1.37326977,
1.35348127, 1.23005667, 7.17238261, 1.08327124, 1.09564307,
1.09371424, 5.57413998, 1.10785148, 1.08750574, 1.08687745,
1.09315894, 1.07541305, 1.07426589, 9.80491142, 8.95850738,
1.07191193, 1.07450384, 1.07208384, 1.07556777, 1.08754213,
1.09113619, 1.06990854, 1.09751627, 1.07513744, 1.07398846,
1.05189518, 1.07329781, 1.07525122, 1.05458198, 1.05977551,
1.07037083, 1.08597627, 1.07956408, 1.04842422, 1.06862143,
1.07634185, 1.08882255, 1.08116088, 1.09394466, 1.06567762,
1.06520645]),
'force_constants': array([5.70610483e-03, 7.62187099e-03, 1.37835945e-02, 2.27448752e-02,
2.96762546e-02, 4.74034274e-02, 6.43227409e-02, 4.24618533e-02,
6.23223647e-02, 9.18677836e-02, 3.23667295e-02, 1.09514071e-01,
1.24932284e-01, 1.24130561e-01, 1.59959428e-01, 1.60347653e-01,
1.54258406e-01, 1.58438585e-01, 2.11801454e-01, 2.69339525e-01,
1.96249293e-01, 2.32687453e-01, 4.00473181e-01, 2.71555256e-01,
3.05521236e-01, 3.11204515e-01, 1.88345703e-01, 5.28568455e-01,
5.57432477e-01, 4.64969930e-01, 6.16034972e-01, 8.94150557e-01,
1.13427349e+00, 8.35478944e-01, 1.08697402e+00, 9.86647768e-01,
9.31329631e-01, 8.62726522e-01, 4.42632044e-01, 9.97733126e-01,
6.81026028e-01, 1.10848547e+00, 1.17154453e+00, 6.06436542e-01,
9.11883540e-01, 9.26649064e-01, 8.77494460e-01, 6.49786318e-01,
1.15190647e+00, 1.09534584e+00, 1.03957669e+00, 1.12861514e+00,
1.02786256e+00, 9.11053317e-01, 1.10014997e+00, 1.18199880e+00,
1.08013989e+00, 1.05321355e+00, 1.33166598e+00, 1.29941315e+00,
1.23672672e+00, 1.20086166e+00, 1.17880428e+00, 1.31651545e+00,
1.04278846e+00, 1.39838546e+00, 2.14688018e+00, 1.42223110e+00,
1.19281725e+00, 1.05827642e+00, 1.34833304e+00, 1.53708975e+00,
1.25241405e+00, 1.51128876e+00, 1.18815658e+00, 1.98164724e+00,
1.61558219e+00, 1.23869558e+00, 1.32785767e+00, 1.72447108e+00,
1.87608555e+00, 2.15593116e+00, 1.87994155e+00, 1.95974135e+00,
1.65798847e+00, 1.30553489e+00, 1.67694935e+00, 1.55554527e+00,
1.40894145e+00, 1.78967330e+00, 1.66533994e+00, 1.34016112e+00,
1.56026101e+00, 1.53787993e+00, 1.87000562e+00, 1.52561656e+00,
2.10995846e+00, 2.10338453e+00, 1.51352429e+00, 1.52771370e+00,
1.51136752e+00, 1.42828515e+00, 8.84183428e+00, 1.35913222e+00,
1.39055651e+00, 1.40280133e+00, 7.17325395e+00, 1.43898911e+00,
1.42982952e+00, 1.43497938e+00, 1.45381663e+00, 1.45025717e+00,
1.45333949e+00, 1.42230982e+01, 1.41526239e+01, 5.07133420e+00,
5.26573910e+00, 5.28034406e+00, 5.42224382e+00, 5.59249890e+00,
5.64216483e+00, 5.56515984e+00, 5.72987536e+00, 5.61650446e+00,
5.61809109e+00, 5.52689918e+00, 5.67723157e+00, 5.69941105e+00,
5.62149646e+00, 5.65348170e+00, 5.79057650e+00, 5.89811582e+00,
5.94156184e+00, 5.79896895e+00, 5.95935863e+00, 6.04147096e+00,
6.16934835e+00, 6.38628757e+00, 6.53434783e+00, 7.80548575e+00,
7.82251253e+00]),
'ir_intensities': array([1.47332729e+00, 1.21240451e+00, 3.43124896e-01, 5.23022976e-01,
1.42087424e+00, 1.28282531e+00, 1.52199887e-01, 6.56667952e-01,
1.86589829e+00, 6.23596027e+01, 2.10589976e+02, 7.14195331e+00,
7.84823625e+00, 4.33263005e+00, 8.98949053e+00, 3.00412323e+00,
1.49567122e+00, 2.81775574e+00, 5.14599419e-01, 4.35220663e+00,
3.44943336e+00, 3.47776622e+00, 1.46508470e+00, 5.87023989e+00,
4.56519423e+00, 9.28976155e+00, 1.60134244e+01, 4.33162788e-01,
2.62743729e+00, 3.97078652e+00, 3.48526098e+00, 2.46803206e+00,
1.08732692e+00, 2.82532219e+00, 9.99619549e-01, 5.78740060e+00,
1.15041226e+01, 7.32519564e+00, 7.91800748e+00, 3.31033555e+00,
6.17963514e+00, 2.64378919e+00, 6.28893258e+00, 8.94663348e+00,
4.69793258e+00, 1.87092708e+00, 2.02837896e+00, 2.18210315e+00,
4.86260503e+00, 3.48852747e+00, 1.40029916e+01, 2.92331881e+00,
3.38311805e+00, 9.00002921e+00, 1.27945860e+01, 7.46138047e+00,
1.10214895e+01, 6.32300502e+00, 2.72977900e+01, 1.15626949e+01,
6.45133761e+00, 2.23529372e+01, 3.62494096e+01, 6.86237254e+01,
3.90576847e+00, 2.82196132e+01, 4.18342731e+01, 1.14216998e+01,
3.36046111e+00, 8.98946943e-01, 8.25617703e+00, 2.39033749e+00,
3.33150501e+00, 1.27479237e+01, 1.75331535e+01, 1.88787327e+00,
2.46350289e+01, 1.01384621e+01, 9.07095144e+00, 1.72822220e+01,
5.29750366e+00, 1.97140136e+01, 1.11048577e+01, 3.92072305e+01,
2.22481324e+01, 9.93312459e+00, 1.86066046e+01, 2.86410982e+00,
6.67911720e-01, 7.77399473e-01, 3.99974565e-01, 6.89682170e+01,
1.00091959e+01, 1.96925750e+01, 4.98689765e+00, 4.10475074e-01,
1.67107704e+01, 1.60231778e+01, 2.56265384e+00, 2.71827450e-01,
9.99001561e-01, 5.91708299e+00, 7.51632994e+00, 9.73264500e-01,
1.22530194e+00, 2.75894336e+00, 1.96902236e+01, 8.13635952e-01,
1.27032213e+00, 6.50717219e-01, 2.37061876e-01, 2.74691910e+00,
1.98547382e+00, 1.69306948e+00, 8.87893460e+00, 4.19955066e+01,
4.09404269e+01, 5.98562293e+01, 7.56486551e+01, 3.46797206e+01,
6.84160771e+00, 1.71834088e+01, 5.99330927e+01, 4.03216336e+01,
8.64817738e+01, 4.42249211e+01, 4.49596675e+00, 7.25351086e+01,
1.01422574e+01, 6.99219982e+01, 2.44899486e+01, 3.37069984e+01,
2.39793897e+01, 8.18418437e+00, 3.78715400e+01, 1.16434057e+01,
5.49630242e+01, 5.58579407e+00, 2.37518055e+01, 1.20893578e+01,
9.87807325e+00])}
Now we have the frequencies, normal modes and IR intensities. In order to animate a specific normal mode, we need to write a routine which selects the mode of interest and returns it in the format required by py3Dmol. We would also like to plot the IR spectrum and, for this, we also need a routine which adds a Gaussian or Lorentzian broadening to the calculated IR spectrum.
# To animate the normal mode we will need both the geometry and the displacements
def get_normal_mode(molecule, normal_mode):
elements = molecule.get_labels()
coords = molecule.get_coordinates_in_angstrom()
natm = molecule.number_of_atoms()
vib_xyz = "%d\n\n" % natm
nm = normal_mode.reshape(natm, 3)
for i in range(natm):
# add coordinates:
vib_xyz += elements[i] + " %15.7f %15.7f %15.7f " % (coords[i,0], coords[i,1], coords[i,2])
# add displacements:
vib_xyz += "%15.7f %15.7f %15.7f\n" % (nm[i,0], nm[i,1], nm[i,2])
return vib_xyz
# Broadening function
def add_broadening(list_ex_energy, list_osci_strength, line_profile='Lorentzian', line_param=10, step=10):
x_min = np.amin(list_ex_energy) - 50
x_max = np.amax(list_ex_energy) + 50
x = np.arange(x_min, x_max, step)
y = np.zeros((len(x)))
#print(x)
#print(y)
# go through the frames and calculate the spectrum for each frame
for xp in range(len(x)):
for e, f in zip(list_ex_energy, list_osci_strength):
if line_profile == 'Gaussian':
y[xp] += f * np.exp(-(
(e - x[xp]) / line_param)**2)
elif line_profile == 'Lorentzian':
y[xp] += 0.5 * line_param * f / (np.pi * (
(x[xp] - e)**2 + 0.25 * line_param**2))
return x, y
After adding the broadening, we can plot the spectrum and then animate a specific normal mode, selected based on its index.
wvn, ir = xtb_vibanalysis_drv.vib_frequencies, xtb_vibanalysis_drv.ir_intensities
wvng, irg = add_broadening(wvn, ir, line_profile='Gaussian', line_param=10, step=2)
# Plot the IR spectra
plt.figure(figsize=(7,4))
# Plot the IR spectrum
plt.plot(wvng, irg, label='IR spectrum')
plt.xlabel('Wavenumber (cm**-1)')
#plt.axis(xmin=3200, xmax=3500)
#plt.axis(ymin=-0.2, ymax=1.5)
plt.ylabel('IR intensity (km/mol)')
plt.title("Calculated IR sepctrum, Kahweol")
plt.legend()
plt.tight_layout(); plt.show()
# Visualize the vibrational mode
index = 64
print("\n\n\n Normal mode %d: %.2f cm-1, %.2f km/mol." % (index,
xtb_vibanalysis_drv.vib_frequencies[index-1],
xtb_vibanalysis_drv.ir_intensities[index-1]))
normal_mode = get_normal_mode(xtb_opt_kahweol, xtb_vibanalysis_drv.normal_modes[index-1])
view = p3d.view(viewergrid=(1,1), width=600, height=300)
view.addModel(normal_mode, "xyz", {'vibrate': {'frames':10,'amplitude':0.75}})
view.setViewStyle({"style": "outline", "width": 0.05})
view.setStyle({"stick": {}, "sphere": {"scale": 0.25}})
view.animate({'loop': 'backAndForth'})
view.zoomTo()
view.show()

Normal mode 64: 1078.75 cm-1, 68.62 km/mol.
3Dmol.js failed to load for some reason. Please check your browser console for error messages.
To make a more interactive normal mode selection, we can create a slider using the ipywidgets Python module for Jupyter notebooks. To make use of the slider widget, we first need a routine which can plot the IR spectrum and animate a specific normal mode selected based on its index.
def vibration_viewer(index):
freq = xtb_vibanalysis_drv.vib_frequencies[index-1]
ir_intens = xtb_vibanalysis_drv.ir_intensities[index-1]
# Plot the IR spectrum
plt.figure(figsize=(7,4))
plt.plot(wvng, irg)
plt.plot(freq, ir_intens, 'o', markersize=10)
plt.xlabel('Wavenumber (cm**-1)')
plt.ylabel('IR intensity (km/mol)')
plt.title("Calculated IR sepctrum, Kahweol")
plt.tight_layout(); plt.show()
normal_mode = get_normal_mode(xtb_opt_kahweol, xtb_vibanalysis_drv.normal_modes[index-1])
view = p3d.view(viewergrid=(1,1), width=600, height=300)
view.addModel(normal_mode, "xyz", {'vibrate': {'frames':10,'amplitude':0.75}})
view.setViewStyle({"style": "outline", "width": 0.05})
view.setStyle({"stick": {}, "sphere": {"scale": 0.25}})
view.animate({'loop': 'backAndForth'})
view.zoomTo()
view.show()
no_norm_modes = xtb_vibanalysis_drv.vib_frequencies.shape[0] # number of vibrational modes
# Note that the slider only works in a Jupyter notebook.
ipywidgets.interact(vibration_viewer,
index=ipywidgets.IntSlider(min=1, max=no_norm_modes, step=1, value=92))
<function __main__.vibration_viewer(index)>