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 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 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
1f902cf
change name for function in tests
Jgmedina95 Feb 4, 2025
3a3cd72
adding selection usage in angle tools
Jgmedina95 Feb 4, 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
2 changes: 2 additions & 0 deletions mdagent/tools/base_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
ComputeOmega,
ComputePhi,
ComputePsi,
RamachandranPlot,
)
from .analysis_tools.distance_tools import ContactsTool, DistanceMatrixTool
from .analysis_tools.inertia import MomentOfInertia
Expand Down Expand Up @@ -66,6 +67,7 @@
"RadiusofGyrationAverage",
"RadiusofGyrationPerFrame",
"RadiusofGyrationPlot",
"RamachandranPlot",
"RDFTool",
"RMSDCalculator",
"Scholar2ResultLLM",
Expand Down
2 changes: 2 additions & 0 deletions mdagent/tools/base_tools/analysis_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
ComputeOmega,
ComputePhi,
ComputePsi,
RamachandranPlot,
)
from .distance_tools import ContactsTool, DistanceMatrixTool
from .inertia import MomentOfInertia
Expand Down Expand Up @@ -40,6 +41,7 @@
"RadiusofGyrationAverage",
"RadiusofGyrationPerFrame",
"RadiusofGyrationPlot",
"RamachandranPlot",
"RMSDCalculator",
"SimulationOutputFigures",
"SolventAccessibleSurfaceArea",
Expand Down
115 changes: 81 additions & 34 deletions mdagent/tools/base_tools/analysis_tools/bond_angles_dihedrals_tool.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import matplotlib.pyplot as plt
import mdtraj as md
from langchain.tools import BaseTool

Expand All @@ -20,19 +21,20 @@ 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."
return "Failed.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."
"Failed. 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)
result = md.compute_angles(traj, angle_indices, periodic=True, opt=True)
return f"Succeeded. {result}"

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"
Expand All @@ -57,7 +59,7 @@ 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."
return " Failed. Trajectory could not be loaded."

if (
not indices
Expand All @@ -67,12 +69,10 @@ def _run(self, traj_file, indices, top_file=None):
for tup in indices
)
):
return (
"Invalid indices. It should be a list of tuples, each containing"
"atom indices as integers."
)
return "Failed. Invalid indices. It should be a list of tuples."

return md.compute_dihedrals(traj, indices, periodic=True, opt=True)
result = md.compute_dihedrals(traj, indices, periodic=True, opt=True)
return f"Succeeded. {result}"

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"
Expand All @@ -81,11 +81,10 @@ 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"""
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

Expand All @@ -97,8 +96,10 @@ 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)
return " Failed. Trajectory could not be loaded."

result = md.compute_phi(traj, periodic=True, opt=True)
return f"Succeeded. {result}"

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"
Expand All @@ -107,10 +108,11 @@ 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"""
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

Expand All @@ -122,8 +124,10 @@ 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)
return "Failed. Trajectory could not be loaded."

result = md.compute_psi(traj, periodic=True, opt=True)
return f"Succeeded. {result}"

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"
Expand All @@ -149,8 +153,10 @@ 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)
return "Failed. Trajectory could not be loaded."

result = md.compute_chi1(traj, periodic=True, opt=True)
return f"Succeeded. {result}"

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"
Expand All @@ -176,8 +182,10 @@ 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)
return "Failed. Trajectory could not be loaded."

result = md.compute_chi2(traj, periodic=True, opt=True)
return f"Succeeded. {result}"

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"
Expand All @@ -204,8 +212,10 @@ 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)
return "Failed. Trajectory could not be loaded."

result = md.compute_chi3(traj, periodic=True, opt=True)
return f"Succeeded. {result}"

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"
Expand All @@ -231,8 +241,10 @@ 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)
return "Failed. Trajectory could not be loaded."

result = md.compute_chi4(traj, periodic=True, opt=True)
return f"Succeeded. {result}"

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"
Expand All @@ -257,8 +269,10 @@ 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)
return "Failed. Trajectory could not be loaded."

result = md.compute_omega(traj, periodic=True, opt=True)
return f"Succeeded. {result}"

except Exception as e:
return f"Failed. {type(e).__name__}: {e}"
Expand All @@ -267,4 +281,37 @@ async def _arun(self, traj_file, top_file=None):
raise NotImplementedError("Async version not implemented")


# class Ramachandran Plot
class RamachandranPlot(BaseTool):
name = "ramachandran_plot"
description = """Generate a Ramachandran plot for the given trajectory, showing
the distribution of phi and psi angles for each frame."""

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 "Failed. Trajectory could not be loaded."

phi_indices, phi_angles = md.compute_phi(traj, periodic=True, opt=True)
psi_indices, psi_angles = md.compute_psi(traj, periodic=True, opt=True)

plt.figure(figsize=(10, 8))
brittyscience marked this conversation as resolved.
Show resolved Hide resolved
plt.scatter(phi_angles.flatten(), psi_angles.flatten(), s=1, color="blue")
plt.xlabel("Phi Angles (radians)")
plt.ylabel("Psi Angles (radians)")
plt.title("Ramachandran Plot")
plt.grid(True)
plt.show()
return "Succeeded. Ramachandran plot generated."

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")
2 changes: 2 additions & 0 deletions mdagent/tools/maketools.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
RadiusofGyrationAverage,
RadiusofGyrationPerFrame,
RadiusofGyrationPlot,
RamachandranPlot,
RDFTool,
Scholar2ResultLLM,
SetUpandRunFunction,
Expand Down Expand Up @@ -86,6 +87,7 @@ def make_all_tools(
RadiusofGyrationAverage(path_registry=path_instance),
RadiusofGyrationPerFrame(path_registry=path_instance),
RadiusofGyrationPlot(path_registry=path_instance),
RamachandranPlot(path_registry=path_instance),
RDFTool(path_registry=path_instance),
SetUpandRunFunction(path_registry=path_instance),
SimulationOutputFigures(path_registry=path_instance),
Expand Down
Loading
Loading