11 from netCDF4
import Dataset
12 import matplotlib.pyplot
as plt
14 import scipy.signal
as sps
15 import plotly.graph_objects
as go
16 import plotly.figure_factory
as ff
17 from plotly.subplots
import make_subplots
18 import ipywidgets
as widgets
19 from ipywidgets
import fixed
21 plt.rcParams[
"figure.figsize"] = 18,10
30 Wrapper function for QHO_prob_plot()
33 Loads in the netCDF dataset and extracts position and energy
34 arrays, passes them off to QHO_prob_plot().
36 @param[in] chain_file The main netCDF output file from a Full VQMC run with write_chains=.TRUE.
38 dat = Dataset(chain_file,
'r', format=
'NETCDF4')
40 positions = dat.variables[
'positions'][:]
41 energies = dat.variables[
'energies'][:]
51 Fancy Plotly plotter for QHO Markov chains
53 @param[in] positions Position array from Markov chain
54 @param[in] energies Energy array from Markov chain
56 hist = ff.create_distplot([positions], [
'Position Distribution'],
57 bin_size=.2, show_rug=
False)
59 fig = make_subplots(specs=[[{
"secondary_y":
True}]])
60 fig.add_trace(go.Scatter(x=positions, y=energies, mode =
'markers', name=
"Energy",
63 colorscale =
'Viridis',
67 fig.add_trace(go.Histogram(hist[
'data'][0]),secondary_y=
True,)
68 fig.add_trace(go.Scatter(hist[
'data'][1]),secondary_y=
True,)
69 fig[
'layout'][
'yaxis'][
'autorange'] =
"reversed"
70 fig[
'layout'][
'yaxis2'][
'showgrid'] =
False
78 Wrapper function for H2_prob_plot()
81 Loads in the netCDF dataset and extracts position and energy
82 arrays, passes them off to H2_prob_plot().
84 @param[in] chain_file The main netCDF output file from a Full VQMC run with write_chains=.TRUE.
85 @param[in] opacity (Optional, default=0.2) Opacity of the electron position scatter plot
87 dat = Dataset(chain_file,
'r', format=
'NETCDF4')
89 positions = dat.variables[
'positions'][:, :]
90 energies = dat.variables[
'energies'][:]
91 bond_length = dat.bond_length
93 R1 = [-bond_length/2, 0.0, 0.0]
94 R2 = [bond_length/2, 0.0, 0.0]
105 Plots the sampled wavefunction for H2plus/H2
107 @param[in] positions XYZ coordinates of Markov chain
108 @param[in] energies Energies of the Markov chains
109 @param[in] R1 The XYZ coordinates of the first atom
110 @param[in] R2 The XYZ coordinates of the second atom
111 @param[in] opacity Opacity of the electron position scatter plot
112 @retval fig Plotly figure object
132 colorscale =
'Viridis',
137 name=
'Markov Chain positions'
181 Energy against @f$ \alpha @f$ plotter for the QHO problem.
184 Plots the VQMC wavefunction energy at each of an array of values for the
185 variational parameter @f$ \alpha @f$, alongside error bars of the standard
186 deviation in each energy.
188 @param[in] results_file The main netCDF output file from a QHO run
189 @param[in] sliceby (Optional) Tuple containing slice intervals for arrays
191 dat = nd.Dataset(results_file,
'r', format=
'NETCDF4')
193 alpha_array = dat.variables[
'Alpha_array'][sliceby[0]:sliceby[1]]
194 energies = dat.variables[
'total_energies'][sliceby[0]:sliceby[1]]
195 variances = dat.variables[
'Uncertainties'][sliceby[0]:sliceby[1]]
197 stdevs = np.sqrt(variances)
198 min_energy = min(energies)
199 min_energy_stdev = stdevs[np.argmin(energies)]
200 opt_alpha = alpha_array[np.argmin(energies)]
202 fig, ax1 = plt.subplots(1, 1, figsize=(8, 8))
204 ax1.set_title(
r'Quantum Harmonic Oscillator Energy with Varying $\alpha$')
205 ax1.plot(alpha_array, energies, marker=
'o', ls=
'--', color=
'blue')
206 ax1.fill_between(alpha_array, energies+stdevs, energies-stdevs, alpha=0.3, color=
'purple')
207 ax1.axvline(0.5, ls=
'-', color=
'black', alpha=0.3)
208 ax1.set_xlabel(
r'$\alpha$')
209 ax1.set_ylabel(
'Energy')
213 print(f
'Optimum alpha: {opt_alpha}')
214 print(f
'Energy: {min_energy} ± {min_energy_stdev}')
220 Scatter plotter of the sampled QHO wavefunction.
223 Plots the sampled positions of a trial QHO wavefunction against the
224 energies at those positions, to illustrate the shape of that wavefunction.
225 Chain output requires the @em write_chains parameter to be @em TRUE.
227 @param[in] chain_file A netCDF dataset of Markov chain and corresponding energies of a VQMC run
228 @param[in] show_analytic Also display the analytical wavefunction
230 dat = nd.Dataset(chain_file,
'r', format=
'NETCDF4')
232 positions = dat.variables[
'positions'][:]
233 energies = dat.variables[
'energies'][:]
236 plt.figure(figsize=(8, 8))
237 plt.title(rf
'Sampled QHO Wavefunction at $\alpha$ = {alpha}')
238 plt.plot(positions, energies,
'o', color=
'purple', markersize=4.0, alpha=0.5, label=
'Sampled Positions')
239 plt.xlabel(
'Sampled Position')
243 pos_array = np.linspace(min(positions), max(positions), 100)
244 analytic = np.exp(-alpha * pos_array**2)
245 plt.plot(pos_array, analytic, color=
'red', alpha=0.8, label=
'Analytic Probability Distribution')
254 @f$ H_{2}^{+} @f$ H-H bond energy and parameter plotter.
257 Plots the H-H bond potential energy curve generated by VQMC at the optimum
258 parameters for each bond length. Plots standard deviation of each energy as
259 a measure of uncertainty. Also plots variational parameter @f$ c @f$ against
260 bond length. Reports equilibrium bond length for the molecule and optimum
263 @param[in] results_file The main netCDF output file from a @f$ H_{2}^{+} @f$ run
264 @param[in] sliceby (Optional) Tuple containing slice intervals for arrays
266 dat = nd.Dataset(results_file,
'r', format=
'NETCDF4')
268 bond_lengths = dat.variables[
'Bondlength_array'][sliceby[0]:sliceby[1]]
269 c_opt = dat.variables[
'Parameter_array'][sliceby[0]:sliceby[1]]
270 energies = dat.variables[
'total_energies'][sliceby[0]:sliceby[1]]
271 variances = dat.variables[
'Uncertainties'][sliceby[0]:sliceby[1]]
273 stdevs = np.sqrt(variances)
274 min_energy = min(energies)
275 min_energy_stdev = stdevs[np.argmin(energies)]
276 min_bond_length = bond_lengths[np.argmin(energies)]
278 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 8))
280 ax1.set_title(
r'$H_{2}^{+}$ bond energy curve')
282 ax1.plot(bond_lengths, energies, marker=
'o', ls=
'--', color=
'blue')
283 ax1.fill_between(bond_lengths, energies+stdevs, energies-stdevs, alpha=0.3, color=
'purple')
284 ax1.axhline(-0.5, ls=
'-', color=
'black', alpha=0.3)
285 ax1.set_xlabel(
r'Bond Length / $a_{0}$')
286 ax1.set_ylabel(
'Energy / Ha')
288 ax2.set_title(
r'Optimised parameter $c$')
289 ax2.plot(bond_lengths, c_opt)
290 ax2.axhline(1/np.sqrt(2), ls=
'-', color=
'black', alpha=0.3)
291 ax2.set_xlabel(
r'Bond Length / $a_{0}$')
292 ax2.set_ylabel(
r'$c$')
297 print(f
'Equilibrium bond length: {min_bond_length} Bohr')
298 print(f
' = {min_bond_length*0.529177} Angstroms')
299 print(f
' at energy: {min_energy} ± {min_energy_stdev} Ha')
306 @f$ H_{2} @f$ H-H bond energy and parameter plotter.
309 Plots the H-H bond potential energy curve generated by VQMC at the optimum
310 parameters for each bond length. Plots standard deviation of each energy as
311 a measure of uncertainty. Also plots variational parameters @f$ a @f$ and
312 @f$ \beta @f$ against bond length. Reports equilibrium bond length for the
313 molecule and optimum energy.
315 @param[in] results_file The main netCDF output file from a @f$ H_{2} @f$ run
316 @param[in] sliceby (Optional) Tuple containing slice intervals for arrays
318 dat = nd.Dataset(results_file,
'r', format=
'NETCDF4')
320 bond_lengths = dat.variables[
'Bondlength_array'][sliceby[0]:sliceby[1]]
321 a_opt = dat.variables[
'Parameter_a_array'][sliceby[0]:sliceby[1]]
322 beta_opt = dat.variables[
'Parameter_beta_array'][sliceby[0]:sliceby[1]]
323 energies = dat.variables[
'total_energies'][sliceby[0]:sliceby[1]]
324 variances = dat.variables[
'Uncertainties'][sliceby[0]:sliceby[1]]
326 stdevs = np.sqrt(variances)
327 min_energy = min(energies)
328 min_energy_stdev = stdevs[np.argmin(energies)]
329 min_bond_length = bond_lengths[np.argmin(energies)]
331 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 8))
333 ax1.set_title(
r'$H_{2}$ bond energy curve')
334 ax1.errorbar(bond_lengths, energies, yerr=stdevs, marker=
'o', ls=
'--', color=
'blue')
335 ax1.fill_between(bond_lengths, energies+stdevs, energies-stdevs, alpha=0.3, color=
'purple')
336 ax1.set_xlabel(
r'Bond Length / $a_{0}$')
337 ax1.set_ylabel(
'Energy / Ha')
339 ax2.set_title(
r'Optimised parameters')
340 ax2.plot(bond_lengths, a_opt, color=
'red')
341 ax2.set_xlabel(
r'Bond Length / $a_{0}$')
342 ax2.set_ylabel(
r'$a$', color=
'red')
343 ax2.tick_params(axis=
'y', labelcolor=
'red')
346 ax2a.plot(bond_lengths, beta_opt, color=
'blue')
347 ax2a.set_ylabel(
r'$\beta$', color=
'blue')
348 ax2a.tick_params(axis=
'y', labelcolor=
'blue')
353 print(f
'Equilibrium bond length: {min_bond_length} Bohr')
354 print(f
' = {min_bond_length*0.529177} Angstroms')
355 print(f
' at energy: {min_energy} ± {min_energy_stdev} Ha')
367 rootgrp = Dataset(equil_file,
"r", format =
"NETCDF4")
368 chain = np.array(rootgrp[
'positions'][:])
369 if len(chain.shape) == 1:
370 plt.plot(range(len(chain)), chain, linewidth=1.0)
371 plt.xlabel(
"Position in chain")
372 plt.ylabel(
"Chain value")
373 plt.title(
"Original Chain")
381 fig, (ax1,ax2,ax3) = plt.subplots(3,1)
382 ax1.plot(range(len(chainx)), chainx, linewidth=1.0)
383 ax2.plot(range(len(chainy)), chainy, linewidth=1.0)
384 ax3.plot(range(len(chainz)), chainz, linewidth=1.0)
391 Wrapper function for interacting with get_autocorrelation_time()
393 @param[in] equil_file Filename of MCMC equilibration run
395 widgets.interact_manual(get_autocorrelation_time, filename=fixed(equil_file),
396 burn=(0, int(0.1*len(np.array(Dataset(equil_file,
"r", format =
"NETCDF4")[
'positions'][:]))), 10),
397 tuning=[(1.0),(1e-1),(1e-2),(1e-3),(1e-4)])
416 rootgrp = Dataset(filename,
"r", format =
"NETCDF4")
417 chain = np.array(rootgrp[
'positions'][:])
418 if len(chain.shape) == 1:
419 acp = sps.fftconvolve(chain,chain[::-1],mode=
'full')
420 acp = acp[int(acp.size / 2):]
424 thin = np.argmax(abs(acp) < tuning)
426 if acp[thin] < tuning:
429 print(
"No thinning value found - tuning may be too aggressive. Defaulting to no thinning, thin=1.")
433 print(
"burning parameter = ", burn)
434 print(
"proposed thinning parameter = ", thin)
436 chain_new = chain[burn::thin]
437 print(
"length of new chain = ", len(chain_new))
440 plt.plot(range(len(acp)), acp, linewidth=1.0)
441 plt.xlabel(
"Position in chain / Lag time")
443 plt.title(
"Autocorrelation function vs lag time")
446 plt.plot(range(len(chain_new)), chain_new, linewidth=1.0)
447 plt.xlabel(
"Position in chain")
448 plt.ylabel(
"Chain value")
449 plt.title(
"New Chain")
462 for c
in [chainx,chainy,chainz]:
463 acp = sps.fftconvolve(c,c[::-1],mode=
'full')
464 acp = acp[int(acp.size / 2):]
468 thin = np.argmax(abs(acp) < tuning)
470 if acp[thin] < tuning:
473 print(
"No thinning value found - tuning may be too aggressive. Defaulting to no thinning, thin=1.")
477 threed_thin.append(thin)
479 chain_new = c[burn::thin]
480 chain_lengths.append(len(chain_new))
483 plt.plot(range(len(acp)), acp, linewidth=1.0)
484 plt.xlabel(
"Position in chain / Lag time")
486 plt.title(
"Autocorrelation function vs lag time")
494 print(
"burning parameter = ", burn)
495 print(
"proposed thinning parameters from the 3 chains: ", threed_thin)
496 print(
"chain lengths from proposed thins", chain_lengths)
498 return burn, threed_thin
508 """Loads the results as a dataset NetCDF object to be passed to other functions
511 filename: The name of the file containing the results, defaults to 'results.nc'. """
514 rootgrp = Dataset(filename)
515 except OSError
as err:
516 print(f
"OS error: {err}")
521 """Loads the global metadata in the results file into a dictionary
524 rootgrp: NetCDF4 dataset object which loaded in using 'load_results()'.
525 verbose: Defaults to true. Prints the value of global attributes which have been loaded
529 for name
in rootgrp.ncattrs():
531 print(
"{} = {}".format(name, getattr(rootgrp, name)))
533 global_dict[name] = getattr(rootgrp, name)
540 """Loads the variables in the results file into a dictionary
543 rootgrp: NetCDF4 dataset object which loaded in using 'load_results()'
544 verbose: Defaults to true. Prints the value of variables which have been loaded
547 for k
in rootgrp.variables.keys():
549 print(
"{} = {}".format(k, rootgrp[k][:]))
550 var_dict[k] = rootgrp[k][:]
556 """Plots the energies against the parameters checked during the grid search
558 variables: Dictionary which contains data about the variables in the netcdf4 object"""
564 x=variables[
'Bondlength_array'],
565 y=variables[
'total_energies'],
568 array=variables[
'Uncertainties'],
574 title=f
"Energies vs Bond Lengths",
575 xaxis_title=
"Bond Length",
586 Plots the energy at each step as the MC converges
589 energies = np.array(rootgrp.variables[
'energy_at_alphas_array'][:])
591 alphas = np.array((rootgrp.variables[
'Alpha_array'][:]))
596 data = go.Scatter(x=alphas, y=energies, mode=
'markers')
597 fig = go.Figure(data)
605 fig = go.Figure(data=go.Volume(
622 """Processes the results output as a result of the parameter search from the NetCDF4 file
625 filename: Defaults to 'results.nc'. The file which contains the data output by the parameter search
637 if (global_attr[
'system'] ==
'QHO'):
641 elif(global_attr[
'system'] ==
'H2plus'):
645 elif(global_attr[
'system'] ==
'H2'):
649 raise Exception(
"Invalid system input into visualisation")
651 return global_attr,variables,main_fig
656 dset = nc.Dataset(filename)
658 energies = dset[
'energies'][:]
660 positions = dset[
'positions'][:]
662 if dset.system ==
'QHO':
668 elif dset.system ==
'H2' or dset.system ==
'H2plus':
670 R1 = [-0.5*dset.bond_length, 0, 0]
671 R2 = [0.5*dset.bond_length, 0, 0]
673 fig = vis.H2_prob_plot(positions, energies, R1, R2)
683 orbital = 1/(((a0**1.5)*(np.sqrt(np.pi)))*\
684 np.exp(np.sqrt((X-x_a)**2+(Y-y_a)**2+(Z-z_a)**2)/a0))
690 orbital = (2-np.linalg.norm(r-R_a)()/a0)/((4*(a0**1.5)*(np.sqrt(2*np.pi)))*np.exp(np.linalg.norm(r-R_a)/(2*a0)))
695 X = r*np.sin(phi)*np.cos(theta)
696 Y = r*np.sin(phi)*np.sin(theta)
705 wfn = np.sqrt(2)*
orb_1s(X,Y,Z,R1) + np.sqrt(2)*
orb_1s(X,Y,Z,R2)
713 """ Function for plotting the wavefunction analytically. Meshgrids can be generated using np.meshgrid(x,y,z)
716 X: Meshgrid of X coordinates
717 Y: Meshgrid of Y coordinates
718 Z: Meshgrid of Z coordinates
723 fig.add_trace(go.Volume(
732 fig.add_trace(go.Scatter3d(
754 x, y, z = np.mgrid[-3:3:40j, -3:3:40j, -3:3:40j]
756 R_1 = (-0.5*bond_length, 0,0)
757 R_2 = (0.5*bond_length, 0,0)
762 density_plot =
plot_3D(x,y,z,density,R_1,R_2)
def H2_prob_plot(positions, energies, R1, R2, opacity)
Plots the sampled wavefunction for H2plus/H2.
def H2plusEnergyPlot(results_file, sliceby=(None, None))
H-H bond energy and parameter plotter.
def load_variables(rootgrp, verbose=True)
Loads the variables in the results file into a dictionary.
def QHOEnergyPlot(results_file, sliceby=(None, None))
Energy against plotter for the QHO problem.
def view_original_trace(equil_file)
Plots the original trace(s) of an MCMC run.
def QHOWfnPlot(chain_file, show_analytic=False)
Scatter plotter of the sampled QHO wavefunction.
def load_results(filename='results.nc')
Loads the results as a dataset NetCDF object to be passed to other functions.
def BurnThinUI(equil_file)
Wrapper function for interacting with get_autocorrelation_time()
def example_H1s_wfn(bond_length=2.0)
def plot_markov_chain(filename)
def orb_1s(X, Y, Z, R_a)
functions plotting the wavefunction ab initio #######
def QHO_prob_plot(positions, energies)
Fancy Plotly plotter for QHO Markov chains.
def polar_to_cart(r, theta, phi)
def QHO_eng_plot(rootgrp, equil=False)
energy_plot() Plots the energy at each step as the MC converges
def H2_eng_plot(variables)
Plots the energies against the parameters checked during the grid search Parameters: variables: Dicti...
def plot_3D(X, Y, Z, wfn)
def H2EnergyPlot(results_file, sliceby=(None, None))
H-H bond energy and parameter plotter.
def lcao_wfn(X, Y, Z, R1, R2, pqn=1)
def get_autocorrelation_time(filename, burn, tuning, plotting=True)
Function which suggests a thinning parameter for a MCMC chain.
def process_main_results(filename='results.nc', verbose=True)
Processes the results output as a result of the parameter search from the NetCDF4 file.
def QHOProbPlot(chain_file)
Wrapper function for QHO_prob_plot()
def HydProbPlot(chain_file, opacity=0.2)
Wrapper function for H2_prob_plot()
def load_global_attr(rootgrp, verbose=True)
Loads the global metadata in the results file into a dictionary.