Save and load data using HDF5 files

Some of richmol objects can be stored and loaded using HDF5 files.

We start from generating field-free rotational energies and matrix elements of dipole moment and polarizability for camphor molecule. For details, see “Rotational dynamics Quickstart”:

[1]:
from richmol.rot import solve, Solution
from richmol.rot import LabTensor
from richmol.rot import Molecule
from richmol.field import CarTens
WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)
[2]:
camphor = Molecule()

camphor.XYZ = ("angstrom",
    "O",     -2.547204,    0.187936,   -0.213755,
    "C",     -1.382858,   -0.147379,   -0.229486,
    "C",     -0.230760,    0.488337,    0.565230,
    "C",     -0.768352,   -1.287324,   -1.044279,
    "C",     -0.563049,    1.864528,    1.124041,
    "C",      0.716269,   -1.203805,   -0.624360,
    "C",      0.929548,    0.325749,   -0.438982,
    "C",      0.080929,   -0.594841,    1.638832,
    "C",      0.791379,   -1.728570,    0.829268,
    "C",      2.305990,    0.692768,    0.129924,
    "C",      0.730586,    1.139634,   -1.733020,
    "H",     -1.449798,    1.804649,    1.756791,
    "H",     -0.781306,    2.571791,    0.321167,
    "H",      0.263569,    2.255213,    1.719313,
    "H",      1.413749,   -1.684160,   -1.316904,
    "H",     -0.928638,   -1.106018,   -2.110152,
    "H",     -1.245108,   -2.239900,   -0.799431,
    "H",      1.816886,   -1.883799,    1.170885,
    "H",      0.276292,   -2.687598,    0.915376,
    "H",     -0.817893,   -0.939327,    2.156614,
    "H",      0.738119,   -0.159990,    2.396232,
    "H",      3.085409,    0.421803,   -0.586828,
    "H",      2.371705,    1.769892,    0.297106,
    "H",      2.531884,    0.195217,    1.071909,
    "H",      0.890539,    2.201894,   -1.536852,
    "H",      1.455250,    0.830868,   -2.487875,
    "H",     -0.267696,    1.035608,   -2.160680)

camphor.dip = [1.21615, -0.30746, 0.01140]

camphor.pol = [[115.80434, -0.58739, 0.03276], \
               [-0.58739, 112.28245, 1.36146], \
               [0.03276, 1.36146, 108.47809]]

camphor.frame = "diag(pol)"

sol = solve(camphor, Jmin=0, Jmax=10)

dip = LabTensor(camphor.dip, sol)
pol = LabTensor(camphor.pol, sol)

Here is how we can store and read Molecule object

[3]:
# store molecule camphor
camphor.store('camphor.h5', comment="S-Camphor structure from the Supersonic expansion FTMW spectra, Kisiel, et al., PCCP 5, 820 (2003)", replace=True)

# read molecule into camphor2
camphor2 = Molecule()
camphor2.read('camphor.h5')

# obtain rotational solution for camphor2
sol2 = solve(camphor2, Jmin=0, Jmax=10)

# compare solutions for camphor and camphor2
print("\ncompare solutions")
for J in sol.keys():
    for sym in sol[J].keys():
        for i in range(sol[J][sym].nstates):
            enr = sol[J][sym].enr[i]
            enr2 = sol2[J][sym].enr[i]
            diff = enr - enr2
            print(J, "%4s"%sym, i, "%12.6f"%enr, "%12.6f"%enr2, "%12.6f"%diff)

compare solutions
0    A 0     0.000000     0.000000     0.000000
1    A 0     0.076070     0.076070     0.000000
1    A 1     0.084863     0.084863     0.000000
1    A 2     0.087741     0.087741     0.000000
2    A 0     0.227612     0.227612     0.000000
2    A 1     0.234126     0.234126     0.000000
2    A 2     0.242759     0.242759     0.000000
2    A 3     0.269138     0.269138     0.000000
2    A 4     0.269736     0.269736     0.000000
3    A 0     0.453583     0.453583     0.000000
3    A 1     0.457678     0.457678     0.000000
3    A 2     0.474864     0.474864     0.000000
3    A 3     0.497349     0.497349     0.000000
3    A 4     0.500187     0.500187     0.000000
3    A 5     0.548850     0.548850     0.000000
3    A 6     0.548929     0.548929     0.000000
4    A 0     0.752988     0.752988     0.000000
4    A 1     0.755209     0.755209     0.000000
4    A 2     0.783441     0.783441     0.000000
4    A 3     0.801159     0.801159     0.000000
4    A 4     0.808865     0.808865     0.000000
4    A 5     0.854125     0.854125     0.000000
4    A 6     0.854669     0.854669     0.000000
4    A 7     0.924882     0.924882     0.000000
4    A 8     0.924891     0.924891     0.000000
5    A 0     1.125354     1.125354     0.000000
5    A 1     1.126433     1.126433     0.000000
5    A 2     1.167533     1.167533     0.000000
5    A 3     1.180186     1.180186     0.000000
5    A 4     1.195808     1.195808     0.000000
5    A 5     1.235838     1.235838     0.000000
5    A 6     1.237902     1.237902     0.000000
5    A 7     1.306557     1.306557     0.000000
5    A 8     1.306635     1.306635     0.000000
5    A 9     1.397421     1.397421     0.000000
5    A 10     1.397421     1.397421     0.000000
6    A 0     1.570646     1.570646     0.000000
6    A 1     1.571134     1.571134     0.000000
6    A 2     1.625927     1.625927     0.000000
6    A 3     1.633993     1.633993     0.000000
6    A 4     1.660444     1.660444     0.000000
6    A 5     1.693825     1.693825     0.000000
6    A 6     1.699453     1.699453     0.000000
6    A 7     1.764922     1.764922     0.000000
6    A 8     1.765299     1.765299     0.000000
6    A 9     1.855364     1.855364     0.000000
6    A 10     1.855374     1.855374     0.000000
6    A 11     1.966491     1.966491     0.000000
6    A 12     1.966492     1.966492     0.000000
7    A 0     2.088963     2.088963     0.000000
7    A 1     2.089172     2.089172     0.000000
7    A 2     2.157544     2.157544     0.000000
7    A 3     2.162142     2.162142     0.000000
7    A 4     2.201829     2.201829     0.000000
7    A 5     2.227777     2.227777     0.000000
7    A 6     2.239923     2.239923     0.000000
7    A 7     2.300048     2.300048     0.000000
7    A 8     2.301363     2.301363     0.000000
7    A 9     2.390006     2.390006     0.000000
7    A 10     2.390062     2.390062     0.000000
7    A 11     2.500692     2.500692     0.000000
7    A 12     2.500693     2.500693     0.000000
7    A 13     2.632097     2.632097     0.000000
7    A 14     2.632097     2.632097     0.000000
8    A 0     2.680384     2.680384     0.000000
8    A 1     2.680471     2.680471     0.000000
8    A 2     2.761852     2.761852     0.000000
8    A 3     2.764240     2.764240     0.000000
8    A 4     2.818738     2.818738     0.000000
8    A 5     2.837268     2.837268     0.000000
8    A 6     2.859247     2.859247     0.000000
8    A 7     2.911899     2.911899     0.000000
8    A 8     2.915538     2.915538     0.000000
8    A 9     3.001493     3.001493     0.000000
8    A 10     3.001727     3.001727     0.000000
8    A 11     3.111556     3.111556     0.000000
8    A 12     3.111564     3.111564     0.000000
8    A 13     3.242557     3.242557     0.000000
8    A 14     3.242557     3.242557     0.000000
8    A 15     3.394236     3.394236     0.000000
8    A 16     3.394236     3.394236     0.000000
9    A 0     3.344956     3.344956     0.000000
9    A 1     3.344991     3.344991     0.000000
9    A 2     3.438826     3.438826     0.000000
9    A 3     3.439984     3.439984     0.000000
9    A 4     3.509795     3.509795     0.000000
9    A 5     3.521809     3.521809     0.000000
9    A 6     3.556686     3.556686     0.000000
9    A 7     3.600292     3.600292     0.000000
9    A 8     3.608650     3.608650     0.000000
9    A 9     3.689945     3.689945     0.000000
9    A 10     3.690724     3.690724     0.000000
9    A 11     3.799224     3.799224     0.000000
9    A 12     3.799259     3.799259     0.000000
9    A 13     3.929651     3.929651     0.000000
9    A 14     3.929652     3.929652     0.000000
9    A 15     4.080960     4.080960     0.000000
9    A 16     4.080960     4.080960     0.000000
9    A 17     4.252910     4.252910     0.000000
9    A 18     4.252910     4.252910     0.000000
10    A 0     4.082701     4.082701     0.000000
10    A 1     4.082715     4.082715     0.000000
10    A 2     4.188630     4.188630     0.000000
10    A 3     4.189164     4.189164     0.000000
10    A 4     4.273832     4.273832     0.000000
10    A 5     4.280902     4.280902     0.000000
10    A 6     4.331072     4.331072     0.000000
10    A 7     4.364892     4.364892     0.000000
10    A 8     4.381250     4.381250     0.000000
10    A 9     4.455414     4.455414     0.000000
10    A 10     4.457593     4.457593     0.000000
10    A 11     4.563844     4.563844     0.000000
10    A 12     4.563980     4.563980     0.000000
10    A 13     4.693498     4.693498     0.000000
10    A 14     4.693502     4.693502     0.000000
10    A 15     4.844296     4.844296     0.000000
10    A 16     4.844296     4.844296     0.000000
10    A 17     5.015900     5.015900     0.000000
10    A 18     5.015900     5.015900     0.000000
10    A 19     5.208118     5.208118     0.000000
10    A 20     5.208118     5.208118     0.000000

Here is how we can store and read rotational solutions, produced by solve function

[4]:
# store solutions sol
sol.store('camphor.h5', replace=True)

# read solutions into sol2
sol2 = Solution()
sol2.read('camphor.h5')

# compute matrix elements of laboratory-frame tensors using sol2 solutions
dip2 = LabTensor(camphor.dip, sol2)
pol2 = LabTensor(camphor.pol, sol2)

# compare tensor matrix elements obtained with sol and sol2

# full matrix representations of dip and dip2 for x, y, and z components
dip_mat = [dip.tomat(form='full', repres='dense', cart=cart) for cart in 'xyz']
dip2_mat = [dip2.tomat(form='full', repres='dense', cart=cart) for cart in 'xyz']

# full matrix representations of pol and pol2 for xx, xy,, xz, yx, ... etc components
pol_mat = [pol.tomat(form='full', repres='dense', cart=cart+cart2) for cart in 'xyz' for cart2 in 'xyz']
pol2_mat = [pol2.tomat(form='full', repres='dense', cart=cart+cart2) for cart in 'xyz' for cart2 in 'xyz']

# compute and print maximal differences
import numpy
dip_diff = [numpy.max(abs(m-m2)) for m,m2 in zip(dip_mat, dip2_mat)]
pol_diff = [numpy.max(abs(m-m2)) for m,m2 in zip(pol_mat, pol2_mat)]

print("max diffs sol-sol2 in dipole matrix elements:", dip_diff)
print("max diffs sol-sol2 in polarizability matrix elements:", pol_diff)
max diffs sol-sol2 in dipole matrix elements: [0.0, 0.0, 0.0]
max diffs sol-sol2 in polarizability matrix elements: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

… and store/read Cartesian tensor operators

[5]:
# store dip and pol matrix elements
dip.store('camphor.h5', replace=True)
pol.store('camphor.h5', replace=True)

# read matrix elements into dip2 and pol2
dip2 = CarTens(filename='camphor.h5', name='dip')
pol2 = CarTens(filename='camphor.h5', name='pol')

# compare matrix elements, calculated and stored/read form file

# full matrix representations of dip and dip2 for x, y, and z components
dip_mat = [dip.tomat(form='full', repres='dense', cart=cart) for cart in 'xyz']
dip2_mat = [dip2.tomat(form='full', repres='dense', cart=cart) for cart in 'xyz']

# full matrix representations of pol and pol2 for xx, xy,, xz, yx, ... etc components
pol_mat = [pol.tomat(form='full', repres='dense', cart=cart+cart2) for cart in 'xyz' for cart2 in 'xyz']
pol2_mat = [pol2.tomat(form='full', repres='dense', cart=cart+cart2) for cart in 'xyz' for cart2 in 'xyz']

# compute and print maximal differences
import numpy
dip_diff = [numpy.max(abs(m-m2)) for m,m2 in zip(dip_mat, dip2_mat)]
pol_diff = [numpy.max(abs(m-m2)) for m,m2 in zip(pol_mat, pol2_mat)]

print("max diffs dip-dip2:", dip_diff)
print("max diffs pol-pol2:", pol_diff)
max diffs dip-dip2: [0.0, 0.0, 0.0]
max diffs pol-pol2: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

The field-free solutions can also be transformed and stored in a tensor form

[6]:
# convert solutions sol2 into tensor form h and store
h = LabTensor(camphor, sol2)
h.store('camphor.h5', comment="S-Camphor field-free energies (in cm^-1)", replace=True)

# read solutions into h2
h2 = CarTens(filename='camphor.h5', name='h')

# compare matrix elements, calculated and stored/read form file

mat = h.tomat(form='full', repres='dense', cart='0')
mat2 = h2.tomat(form='full', repres='dense', cart='0')
diff = numpy.max(abs(mat-mat2))
print("max diffs:", diff)

max diffs: 0.0
[ ]: