Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bond angles dihedrals #139

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5dcba38
bond angles dihedrals backbone code
brittyscience Jun 7, 2024
520e16c
path registry and code revisions
brittyscience Jun 8, 2024
3b1539f
revised class descriptions for clarity
brittyscience Jun 8, 2024
6829a49
merge from main
brittyscience Jun 8, 2024
06d5561
unit test
brittyscience Jun 9, 2024
64e64b9
minor changes to the bond_angle file
brittyscience Jun 9, 2024
a142cf9
minor changes to the bond_angle file
brittyscience Jun 9, 2024
5019578
added try except to every run function
brittyscience Jun 9, 2024
fd600b9
Merge branch 'main' into bond_angles_dihedrals
brittyscience Jun 12, 2024
327925d
a hopeful small correction to pass the git check
brittyscience Jun 13, 2024
847f764
updated the toools to include Ram plot.
brittyscience Jun 14, 2024
e732d23
added type hint, added graphs, save to path and file, added helper f…
brittyscience Jun 16, 2024
7ebb3a4
updated unit test
brittyscience Jun 21, 2024
7de6997
Co-authored-by: Quinny Campbell <[email protected]>
brittyscience Jun 24, 2024
244de1c
did some tweaking to try to get unit test to be functional.
brittyscience Jun 24, 2024
615b895
waving white flag. Need a second set of eyes to see what I am missin…
brittyscience Jun 25, 2024
7cb976b
Merge branch 'main' into bond_angles_dihedrals
Jgmedina95 Jan 23, 2025
16c0be9
ComputeAngle tool implementation
Jgmedina95 Jan 24, 2025
5467132
removing unnecesary angle tools
Jgmedina95 Jan 24, 2025
59071e3
adding small peptide traj in conftest.py
Jgmedina95 Jan 24, 2025
15b7ccc
adding initial tests that check correct workflow for angle tool
Jgmedina95 Jan 24, 2025
52aae41
redoing chi angle analysis for computeangle tools
Jgmedina95 Jan 27, 2025
f834550
typo
Jgmedina95 Jan 27, 2025
01ebab5
fixing input error (Removing path registry as input) in the analyze a…
Jgmedina95 Jan 28, 2025
777797d
fixing typos and input descriptions
Jgmedina95 Jan 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion mdagent/tools/base_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
from .analysis_tools.bond_angles_dihedrals_tool import (
ComputeAngles,
ComputeChi1,
ComputeChi2,
ComputeChi3,
ComputeChi4,
ComputeDihedrals,
ComputeOmega,
ComputePhi,
ComputePsi,
)
from .analysis_tools.plot_tools import SimulationOutputFigures
from .analysis_tools.ppi_tools import PPIDistance
from .analysis_tools.rdf_tool import RDFTool
Expand All @@ -23,12 +34,21 @@

__all__ = [
"CleaningToolFunction",
"ComputeAngles",
"ComputeChi1",
"ComputeChi2",
"ComputeChi3",
"ComputeChi4",
"ComputeDihedrals",
"ComputeOmega",
"ComputePhi",
"ComputePsi",
"ListRegistryPaths",
"MapPath2Name",
"ModifyBaseSimulationScriptTool",
"ProteinName2PDBTool",
"PackMolTool",
"PPIDistance",
"ProteinName2PDBTool",
"RadiusofGyrationAverage",
"RadiusofGyrationPerFrame",
"RadiusofGyrationPlot",
Expand Down
20 changes: 20 additions & 0 deletions mdagent/tools/base_tools/analysis_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
from .bond_angles_dihedrals_tool import (
ComputeAngles,
ComputeChi1,
ComputeChi2,
ComputeChi3,
ComputeChi4,
ComputeDihedrals,
ComputeOmega,
ComputePhi,
ComputePsi,
)
from .plot_tools import SimulationOutputFigures
from .ppi_tools import PPIDistance
from .rgy import RadiusofGyrationAverage, RadiusofGyrationPerFrame, RadiusofGyrationPlot
from .rmsd_tools import RMSDCalculator
from .vis_tools import VisFunctions, VisualizeProtein

__all__ = [
"ComputeAngles",
"ComputeChi1",
"ComputeChi2",
"ComputeChi3",
"ComputeChi4",
"ComputeDihedrals",
"ComputeOmega",
"ComputePhi",
"ComputePsi",
"PPIDistance",
"RadiusofGyrationAverage",
"RadiusofGyrationPerFrame",
Expand Down
270 changes: 270 additions & 0 deletions mdagent/tools/base_tools/analysis_tools/bond_angles_dihedrals_tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
import mdtraj as md
from langchain.tools import BaseTool

from mdagent.utils import PathRegistry, load_single_traj


class ComputeAngles(BaseTool):
name = "compute_angles"
description = """Calculate the bond angles for the given sets of three atoms in
each snapshot, and provide a list of indices specifying which atoms are involved
in each bond angle calculation.."""

path_registry: PathRegistry | None = None

def __init__(self, path_registry: PathRegistry):
super().__init__()
self.path_registry = path_registry

def _run(self, traj_file, angle_indices, top_file=None):
try:
traj = load_single_traj(self.path_registry, traj_file, top_file)
if not traj:
return "Trajectory could not be loaded."

if (
not angle_indices
or not isinstance(angle_indices, list)
or not all(len(indices) == 3 for indices in angle_indices)
):
return (
"Invalid angle_indices. It should be a list of tuples, each "
"containing three atom indices."
)

return md.compute_angles(traj, angle_indices, periodic=True, opt=True)

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"

async def _arun(self, traj_file, angle_indices, top_file=None):
raise NotImplementedError("Async version not implemented")


class ComputeDihedrals(BaseTool):
name = "compute_dihedrals"
description = """Calculate the dihedral angles for the given groups of four atoms
in each snapshot, and provide a list of dihedral angles along with a list of
indices specifying which atoms are involved in each dihedral angle calculation."""

path_registry: PathRegistry | None = None

def __init__(self, path_registry: PathRegistry):
super().__init__()
self.path_registry = path_registry

def _run(self, traj_file, indices, top_file=None):
try:
traj = load_single_traj(self.path_registry, traj_file, top_file)
if not traj:
return "Trajectory could not be loaded."

if (
not indices
or not isinstance(indices, list)
or not all(
isinstance(tup, tuple) and all(isinstance(i, int) for i in tup)
for tup in indices
)
):
return (
"Invalid indices. It should be a list of tuples, each containing"
"atom indices as integers."
)

return md.compute_dihedrals(traj, indices, periodic=True, opt=True)

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"

async def _arun(self, traj_file, indices, top_file=None):
raise NotImplementedError("Async version not implemented")


class ComputePsi(BaseTool):
name = "compute_psi"
description = """Calculate the psi angles for each snapshot, providing a list of
psi angles for each frame in the trajectory and a list of indices specifying the
atoms involved in calculating each psi angle"""

path_registry: PathRegistry | None = None

def __init__(self, path_registry: PathRegistry):
super().__init__()
self.path_registry = path_registry

def _run(self, traj_file, top_file=None):
try:
traj = load_single_traj(self.path_registry, traj_file, top_file)
if not traj:
return "Trajectory could not be loaded."
return md.compute_psi(traj, periodic=True, opt=True)

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"

async def _arun(self, traj_file, top_file=None):
raise NotImplementedError("Async version not implemented")


class ComputePhi(BaseTool):
name = "compute_phi"
description = """This class calculates phi torsion angles and provides a list of phi
angles and indices specifying which atoms are involved in the calculations"""

path_registry: PathRegistry | None = None

def __init__(self, path_registry: PathRegistry):
super().__init__()
self.path_registry = path_registry

def _run(self, traj_file, top_file=None):
try:
traj = load_single_traj(self.path_registry, traj_file, top_file)
if not traj:
return "Trajectory could not be loaded."
return md.compute_phi(traj, periodic=True, opt=True)

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"

async def _arun(self, traj_file, top_file=None):
raise NotImplementedError("Async version not implemented")


class ComputeChi1(BaseTool):
name = "compute_chi1"
description = """Calculate the chi1 angles (the first side chain torsion angle
formed between four atoms around the CA-CB axis) for each snapshot, providing a
list of chi1 angles and indices specifying the atoms involved in each chi1 angle
calculation."""

path_registry: PathRegistry | None = None

def __init__(self, path_registry: PathRegistry):
super().__init__()
self.path_registry = path_registry

def _run(self, traj_file, top_file=None):
try:
traj = load_single_traj(self.path_registry, traj_file, top_file)
if not traj:
return "Trajectory could not be loaded."
return md.compute_chi1(traj, periodic=True, opt=True)

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"

async def _arun(self, traj_file, top_file=None):
raise NotImplementedError("Async version not implemented")


class ComputeChi2(BaseTool):
name = "compute_chi2"
description = """Calculate the chi2 angles (the second side chain torsion angle
formed between four atoms around the CB-CG axis) for each snapshot, providing a
list of chi2 angles and a list of indices specifying the atoms involved in
calculating each chi2 angle."""

path_registry: PathRegistry | None = None

def __init__(self, path_registry: PathRegistry):
super().__init__()
self.path_registry = path_registry

def _run(self, traj_file, top_file=None):
try:
traj = load_single_traj(self.path_registry, traj_file, top_file)
if not traj:
return "Trajectory could not be loaded."
return md.compute_chi2(traj, periodic=True, opt=True)

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"

async def _arun(self, traj_file, top_file=None):
raise NotImplementedError("Async version not implemented")


class ComputeChi3(BaseTool):
name = "compute_chi3"
description = """Calculate the chi3 angles (the third side chain torsion angle
formed between four atoms around the CG-CD axis) for each snapshot in the
trajectory, providing a list of chi3 angles and indices specifying the atoms
involved in the calculation of each chi3 angle. Note: Only the residues ARG, GLN,
GLU, LYS, and MET have these atoms."""

path_registry: PathRegistry | None = None

def __init__(self, path_registry: PathRegistry):
super().__init__()
self.path_registry = path_registry

def _run(self, traj_file, top_file=None):
try:
traj = load_single_traj(self.path_registry, traj_file, top_file)
if not traj:
return "Trajectory could not be loaded."
return md.compute_chi3(traj, periodic=True, opt=True)

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"

async def _arun(self, traj_file, top_file=None):
raise NotImplementedError("Async version not implemented")


class ComputeChi4(BaseTool):
name = "compute_chi4"
description = """Calculate the chi4 angles (the fourth side chain torsion angle
formed between four atoms around the CD-CE or CD-NE axis) for each snapshot in the
trajectory, providing a list of indices specifying which atoms are involved in the
chi4 angle calculations. """

path_registry: PathRegistry | None = None

def __init__(self, path_registry: PathRegistry):
super().__init__()
self.path_registry = path_registry

def _run(self, traj_file, top_file=None):
try:
traj = load_single_traj(self.path_registry, traj_file, top_file)
if not traj:
return "Trajectory could not be loaded."
return md.compute_chi4(traj, periodic=True, opt=True)

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"

async def _arun(self, traj_file, top_file=None):
raise NotImplementedError("Async version not implemented")


class ComputeOmega(BaseTool):
name = "compute_omega"
description = """Calculate the omega angles for each snapshot in the trajectory,
providing a list of indices specifying which atoms are involved in the omega angle
calculations.."""

path_registry: PathRegistry | None = None

def __init__(self, path_registry: PathRegistry):
super().__init__()
self.path_registry = path_registry

def _run(self, traj_file, top_file=None):
try:
traj = load_single_traj(self.path_registry, traj_file, top_file)
if not traj:
return "Trajectory could not be loaded."
return md.compute_omega(traj, periodic=True, opt=True)
brittyscience marked this conversation as resolved.
Show resolved Hide resolved

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"

async def _arun(self, traj_file, top_file=None):
raise NotImplementedError("Async version not implemented")


# class Ramachandran Plot
brittyscience marked this conversation as resolved.
Show resolved Hide resolved
18 changes: 18 additions & 0 deletions mdagent/tools/maketools.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@

from .base_tools import (
CleaningToolFunction,
ComputeAngles,
ComputeChi1,
ComputeChi2,
ComputeChi3,
ComputeChi4,
ComputeDihedrals,
ComputeOmega,
ComputePhi,
ComputePsi,
ListRegistryPaths,
ModifyBaseSimulationScriptTool,
PackMolTool,
Expand Down Expand Up @@ -46,6 +55,15 @@ def make_all_tools(

# add base tools
base_tools = [
ComputeAngles(path_registry=path_instance),
ComputeChi1(path_registry=path_instance),
ComputeChi2(path_registry=path_instance),
ComputeChi3(path_registry=path_instance),
ComputeChi4(path_registry=path_instance),
ComputeDihedrals(path_registry=path_instance),
ComputeOmega(path_registry=path_instance),
ComputePhi(path_registry=path_instance),
ComputePsi(path_registry=path_instance),
CleaningToolFunction(path_registry=path_instance),
ListRegistryPaths(path_registry=path_instance),
ProteinName2PDBTool(path_registry=path_instance),
Expand Down
12 changes: 11 additions & 1 deletion mdagent/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
from .data_handling import load_single_traj, load_traj_with_ref, save_plot, save_to_csv
from .makellm import _make_llm
from .path_registry import FileType, PathRegistry
from .set_ckpt import SetCheckpoint

__all__ = ["_make_llm", "PathRegistry", "FileType", "SetCheckpoint"]
__all__ = [
"load_single_traj",
"load_traj_with_ref",
"save_plot",
"save_to_csv",
"_make_llm",
"FileType",
"PathRegistry",
"SetCheckpoint",
]
Loading
Loading