diff --git a/examples/dppe/dppe.py b/examples/dppe/dppe.py index 89fb4f3..5a37c59 100644 --- a/examples/dppe/dppe.py +++ b/examples/dppe/dppe.py @@ -7,6 +7,7 @@ logging.basicConfig(format=FORMAT, level=logging.DEBUG) import stk + from conformational_sampling.catalytic_reaction_complex import ( ReductiveEliminationComplex, ) @@ -69,6 +70,7 @@ start_visualization = False if start_visualization: import panel as pn + from conformational_sampling.visualization import ConformationalSamplingDashboard pn.serve( diff --git a/examples/suzuki/suzuki.py b/examples/suzuki/suzuki.py index c79f550..0f12118 100644 --- a/examples/suzuki/suzuki.py +++ b/examples/suzuki/suzuki.py @@ -7,6 +7,7 @@ logging.basicConfig(format=FORMAT, level=logging.DEBUG) import stk + from conformational_sampling.catalytic_reaction_complex import ( ReductiveEliminationComplex, ) @@ -63,6 +64,20 @@ reactive_ligand_2=reactive_ligand_2, config=config, ) + +# set to True to start visualization after conformer reaction paths have already +# been generated +start_visualization = False +if start_visualization: + import panel as pn + + from conformational_sampling.visualization import ConformationalSamplingDashboard + + pn.serve( + ConformationalSamplingDashboard(reactive_complex).app(), show=False, port=5006 + ) + raise SystemExit + # generates conformers including multi-phase optimization and uniqueness filtering reactive_complex.gen_conformers() diff --git a/src/conformational_sampling/analyze.py b/src/conformational_sampling/analyze.py index 1e1e830..3e2206a 100644 --- a/src/conformational_sampling/analyze.py +++ b/src/conformational_sampling/analyze.py @@ -8,7 +8,7 @@ import numpy as np import stk from openbabel import pybel as pb -from pyGSM.utilities.units import EV_TO_AU, KCAL_MOL_PER_AU +from pyGSM.utilities.units import EV_TO_AU, KCAL_MOL_PER_AU, KJ_MOL_TO_AU from rdkit import Chem from rdkit.Chem import rdmolops, rdMolTransforms from rdkit.Chem.rdmolfiles import MolFromMolBlock, MolToMolBlock @@ -114,7 +114,9 @@ def __post_init__(self): for node in ob_string_nodes: mol_block = node.write('mol') self.string_nodes.append(MolFromMolBlock(mol_block, removeHs=False)) - self.string_energies.append(float(mol_block.split()[0]) * EV_TO_AU * KCAL_MOL_PER_AU) + # correcting for mismatched units based on the unit conversion in pyGSM + # when writing to XYZ files + self.string_energies.append(float(mol_block.split()[0]) / KJ_MOL_TO_AU) else: self.string_nodes = [ MolFromMolBlock(node.write("mol"), removeHs=False) diff --git a/src/conformational_sampling/visualization.py b/src/conformational_sampling/visualization.py index bfd8b3c..2865cbe 100644 --- a/src/conformational_sampling/visualization.py +++ b/src/conformational_sampling/visualization.py @@ -2,37 +2,41 @@ # %reload_ext autoreload # %autoreload 2 import os -import re import pickle +import re + # from IPython.display import display import numpy as np import pandas as pd from rdkit import Chem -from rdkit.Chem.rdchem import Mol from rdkit.Chem import rdMolTransforms -from rdkit.Chem.rdmolfiles import MolToPDBBlock, MolToXYZBlock +from rdkit.Chem.rdchem import Mol from rdkit.Chem.rdMolAlign import AlignMol +from rdkit.Chem.rdmolfiles import MolToPDBBlock, MolToXYZBlock print('Made it halfway through imports!') -import param -import hvplot.pandas # noqa import holoviews as hv -from holoviews import opts, Slope -from holoviews.streams import Selection1D +import hvplot.pandas # noqa import panel as pn -from panel_chemistry.pane import \ - NGLViewer # panel_chemistry needs to be imported before you run pn.extension() +import param +from holoviews import Slope, opts +from holoviews.streams import Selection1D +from panel_chemistry.pane import NGLViewer + +# panel_chemistry needs to be imported before you run pn.extension() from panel_chemistry.pane.ngl_viewer import EXTENSIONS + pn.extension('bokeh') hv.extension('bokeh') pn.extension(comms='vscode') pn.extension('tabulator') pn.extension("ngl_viewer", sizing_mode="stretch_width") from pathlib import Path + import openbabel as ob -from conformational_sampling.analyze import Conformer, System, systems, exclude_confs +from conformational_sampling.analyze import Conformer, System, exclude_confs, systems from conformational_sampling.utils import free_energy_diff print('Finished imports!') @@ -146,7 +150,7 @@ def dataframe(self): ) # self.df.sort_values(axis=0, by='relative_ts_energy (kcal/mol)')['conf_idx'].to_csv(Path.home() / 'confs_df.csv') - self.df.to_csv(Path.home() / 'df.csv') + self.df.to_csv('conformer_data.csv') # return pn.widgets.Tabulator(self.df) plot = self.df.hvplot( @@ -172,13 +176,19 @@ def dataframe(self): # testing out generating descriptive statistics pd.options.display.width = 200 # self.df.groupby('mol_name').describe().to_csv(Path.home() / 'Lilly' / 'py-conformational-sampling' / 'summary_statistics.csv') - sum_stats_file = Path.home() / 'Lilly' / 'py-conformational-sampling' / 'summary_statistics.csv' + # sum_stats_file = Path.home() / 'Lilly' / 'py-conformational-sampling' / 'summary_statistics.csv' group_by = self.df.groupby(['mol_name', 'Product stereochemistry']) - sum_stats = group_by[[ - 'activation energy (kcal/mol)', - 'relative_ts_energy (kcal/mol)', - 'forming_bond_torsion (deg)', - ]].describe(percentiles=[0.5]).T.to_csv(sum_stats_file, float_format=lambda x: f' {x:.6f}') + sum_stats = ( + group_by[ + [ + 'activation energy (kcal/mol)', + 'relative_ts_energy (kcal/mol)', + 'forming_bond_torsion (deg)', + ] + ] + .describe(percentiles=[0.5]) + .T.to_csv('summary_statistics.csv', float_format=lambda x: f' {x:.6f}') + ) # sum_stats_file.write_text(sum_stats) return self.df.hvplot.explorer(