Source code for mdadash.backend.analyses.energies
"""
Widgets for various simulation energies
"""
import logging
from collections import deque
from typing import ClassVar
import matplotlib.pyplot as plt
from IPython.display import display
from mdadash.backend.widgets.base import WidgetBase
logger = logging.getLogger(__name__)
[docs]
class EnergyWidgetBase:
"Base class for Energy Widgets"
name = ""
data_key = ""
y_label = "Energy ( kJ / mol )"
_notes = (
"Energies are only available for streaming trajectories and only if the "
"simulation engine is configured to send them."
)
_inputs: ClassVar = [
{
"attribute": "maxlen",
"name": "Max values",
"description": "Max values to show in plot",
"type": "int",
},
{
"attribute": "title",
"name": "Title",
"description": "Title for the plot",
"type": "str",
},
{
"attribute": "x_type",
"name": "X-axis",
"type": "toggle",
"options": [
{"name": "Time", "value": "time"},
{"name": "Step", "value": "step"},
],
},
]
def __init__(self):
super().__init__()
self.title = self.name
self.default_maxlen = 100
self.maxlen = self.default_maxlen
self.x_type = "time"
self.x_values = None
self._setup_plot()
self._reset_plot_values()
def _setup_plot(self):
"""Setup matplotlib plot"""
self.fig, self.ax = plt.subplots()
(self.plot,) = self.ax.plot([], [])
self._set_title()
self.ax.set_ylabel(self.y_label)
self.ax.grid(True)
def _reset_plot_values(self):
"""Reset plot values"""
self.steps = deque(maxlen=self.maxlen)
self.times = deque(maxlen=self.maxlen)
self.y_values = deque(maxlen=self.maxlen)
self._set_x_values()
def _set_title(self):
"""Set plot title"""
self.ax.set_title(self.title, y=1.05)
def _set_x_values(self):
"""Set the values for the x-axis"""
if self.x_type == "step":
x_label = "Step"
self.x_values = self.steps
else:
x_label = "Time (ps)"
self.x_values = self.times
self.ax.set_xlabel(x_label)
[docs]
def on_post_create(self):
"""on_post_create handler"""
self._set_title()
self._reset_plot_values()
[docs]
def on_input_change(self, attribute, _old_value, new_value):
"""on_input_change handler"""
if attribute == "maxlen":
if new_value < 0:
self.maxlen = self.default_maxlen
self._reset_plot_values()
elif attribute == "title":
self._set_title()
elif attribute == "x_type":
self._set_x_values()
[docs]
def run_every_frame(self):
"""every-frame run handler"""
ts = self.u.trajectory.ts # pylint: disable=no-member
if self.data_key not in ts.data:
return # pragma: no cover
self.steps.append(ts.data["step"])
self.times.append(ts.data["time"])
self.y_values.append(ts.data[self.data_key])
# update plot
self.plot.set_data(self.x_values, self.y_values)
self.ax.relim()
self.ax.autoscale_view()
self.fig.canvas.draw()
display(self.fig)
[docs]
class AbsoluteTemperature(EnergyWidgetBase, WidgetBase):
"""Absolute Temperature"""
name = "Absolute Temperature"
description = "Plot of Absolute Temperature"
data_key = "temperature"
y_label = "Temperature ( K )"
[docs]
class TotalEnergy(EnergyWidgetBase, WidgetBase):
"""Total Energy"""
name = "Total Energy"
description = "Plot of Total Energy"
data_key = "total_energy"
[docs]
class PotentialEnergy(EnergyWidgetBase, WidgetBase):
"""Potential energy"""
name = "Potential energy"
description = "Plot of Potential Energy"
data_key = "potential_energy"
[docs]
class VanDerWaalsEnergy(EnergyWidgetBase, WidgetBase):
"""Van Der Waals Energy"""
name = "Van Der Waals Energy"
description = "Plot of Van Der Waals Energy"
data_key = "van_der_walls_energy"
[docs]
class CoulombInteractionEnergy(EnergyWidgetBase, WidgetBase):
"""Coulomb Interaction Energy"""
name = "Coulomb Interaction Energy"
description = "Plot of Coulomb Interaction Energy"
data_key = "coulomb_energy"
[docs]
class BondsEnergy(EnergyWidgetBase, WidgetBase):
"""Bonds Energy"""
name = "Bonds Energy"
description = "Plot of Bonds Energy"
data_key = "bonds_energy"
[docs]
class AnglesEnergy(EnergyWidgetBase, WidgetBase):
"""Angles Energy"""
name = "Angles Energy"
description = "Plot of Angles Energy"
data_key = "angles_energy"
[docs]
class DihedralsEnergy(EnergyWidgetBase, WidgetBase):
"""Dihedrals Energy"""
name = "Dihedrals Energy"
description = "Plot of Dihedrals Energy"
data_key = "dihedrals_energy"
[docs]
class ImproperDihedralsEnergy(EnergyWidgetBase, WidgetBase):
"""Improper Dihedrals Energy"""
name = "Improper Dihedrals Energy"
description = "Plot of Improper Dihedrals Energy"
data_key = "improper_dihedrals_energy"