-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Compare sampling methods for the same molecule (#22)
* Add script for running all methods for a single XYZ * Script for running all sampling strategies * Add comparison function * Compute heat capacities too * First notebook for comparing sampling methods * Scale perturbations by number of atoms involved * Measure the enthalpy too * Add enthalpy to the comaprison
- Loading branch information
Showing
12 changed files
with
1,118 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
"""Tools for assessing the quality of a Hessian compared to a true one""" | ||
from dataclasses import dataclass | ||
|
||
import ase | ||
from ase import units | ||
import numpy as np | ||
from ase.vibrations import VibrationsData | ||
from pmutt.statmech import StatMech, presets | ||
|
||
|
||
@dataclass | ||
class HessianQuality: | ||
"""Measurements of the quality of a Hessian""" | ||
|
||
# Thermodynamics | ||
zpe: float | ||
"""Zero point energy (kcal/mol)""" | ||
zpe_error: float | ||
"""Different between the ZPE and the target one""" | ||
cp: list[float] | ||
"""Heat capacity as a function of temperature (units: kcal/mol/K)""" | ||
cp_error: list[float] | ||
"""Difference between known and approximate heat capacity as a function of temperature (units: kcal/mol/K)""" | ||
h: list[float] | ||
"""Enthalpy as a function of temperature (units: kcal/mol)""" | ||
h_error: list[float] | ||
"""Error between known and approximate enthalpy as a function of temperature (units: kcal/mol)""" | ||
temps: list[float] | ||
"""Temperatures at which Cp was evaluated (units: K)""" | ||
|
||
# Vibrations | ||
vib_freqs: list[float] | ||
"""Vibrational frequencies for our hessian (units: cm^-1)""" | ||
vib_errors: list[float] | ||
"""Error between each frequency and the corresponding mode in the known hessian""" | ||
vib_mae: float | ||
"""Mean absolute error for the vibrational modes""" | ||
|
||
|
||
def compare_hessians(atoms: ase.Atoms, known_hessian: np.ndarray, approx_hessian: np.ndarray) -> HessianQuality: | ||
"""Compare two different hessians for same atomic structure | ||
Args: | ||
atoms: Structure | ||
known_hessian: 2D form of the target Hessian | ||
approx_hessian: 2D form of an approximate Hessian | ||
Returns: | ||
Collection of the performance metrics | ||
""" | ||
|
||
# Start by making a vibration data object | ||
known_vibs: VibrationsData = VibrationsData.from_2d(atoms, known_hessian) | ||
approx_vibs: VibrationsData = VibrationsData.from_2d(atoms, approx_hessian) | ||
|
||
# Compare the vibrational frequencies on the non-zero modes | ||
known_freqs = known_vibs.get_frequencies() | ||
is_real = np.isreal(known_freqs) | ||
approx_freqs = approx_vibs.get_frequencies() | ||
freq_error = np.subtract(approx_freqs[is_real], known_freqs[is_real]) | ||
freq_mae = np.abs(freq_error).mean() | ||
|
||
# Compare the enthalpy and heat capacity | ||
# TODO (wardlt): Might actually want to compute the symmetry number | ||
known_harm = StatMech(vib_wavenumbers=np.real(known_freqs[is_real]), atoms=atoms, symmetrynumber=1, **presets['harmonic']) | ||
approx_harm = StatMech(vib_wavenumbers=np.real(approx_freqs[is_real]), atoms=atoms, symmetrynumber=1, **presets['harmonic']) | ||
|
||
temps = np.linspace(1., 373, 128) | ||
known_cp = np.array([known_harm.get_Cp('kcal/mol/K', T=t) for t in temps]) | ||
approx_cp = np.array([approx_harm.get_Cp('kcal/mol/K', T=t) for t in temps]) | ||
known_h = np.array([known_harm.get_H('kcal/mol', T=t) for t in temps]) | ||
approx_h = np.array([approx_harm.get_H('kcal/mol', T=t) for t in temps]) | ||
|
||
# Assemble into a result object | ||
return HessianQuality( | ||
zpe=approx_vibs.get_zero_point_energy() * units.mol / units.kcal, | ||
zpe_error=(approx_vibs.get_zero_point_energy() - known_vibs.get_zero_point_energy()) * units.mol / units.kcal, | ||
vib_freqs=np.real(approx_freqs[is_real]).tolist(), | ||
vib_errors=np.abs(freq_error), | ||
vib_mae=freq_mae, | ||
cp=approx_cp.tolist(), | ||
cp_error=(known_cp - approx_cp).tolist(), | ||
h=approx_h, | ||
h_error=(known_h - approx_h).tolist(), | ||
temps=temps.tolist() | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#! /bin/bash | ||
|
||
xyz=../data/exact/caffeine_pm7_None.xyz | ||
for step_size in 0.02; do | ||
# Do the randomized methods | ||
for method in 0_random-directions-same-distance.ipynb 1_random-directions-variable-distance.ipynb; do | ||
papermill -p starting_geometry $xyz -p step_size $step_size $method last.ipynb | ||
done | ||
|
||
# Test with different reductions for "along axes" | ||
notebook=2_displace-along-axes.ipynb | ||
for n in 2 4 8; do | ||
papermill -p starting_geometry $xyz -p perturbs_per_evaluation $n -p step_size $step_size $notebook last.ipynb | ||
done | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#! /bin/bash | ||
|
||
notebook=$1 | ||
dbs=$(find ../1_explore-sampling-methods/data/ -name "caffeine_pm7_None*.db") | ||
for db in $dbs; do | ||
echo $db | ||
papermill -p db_path "$db" -p max_size 5000 $notebook last.ipynb | ||
done |
Oops, something went wrong.