-
Notifications
You must be signed in to change notification settings - Fork 97
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
foldx Buildmodel mutation interfact - convenience interface #374
base: main
Are you sure you want to change the base?
Changes from 5 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# This source code is part of the Biotite package and is distributed | ||
# under the 3-Clause BSD License. Please see 'LICENSE.rst' for further | ||
# information. | ||
|
||
""" | ||
A subpackage for static ligand docking with *FoldX*. | ||
""" | ||
|
||
__name__ = "biotite.application.foldX" | ||
__author__ = "Mojmir Mutny" | ||
|
||
from .app import * |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,190 @@ | ||||||||||||||||||||||
# This source code is part of the Biotite package and is distributed | ||||||||||||||||||||||
# under the 3-Clause BSD License. Please see 'LICENSE.rst' for further | ||||||||||||||||||||||
# information. | ||||||||||||||||||||||
|
||||||||||||||||||||||
__name__ = "biotite.application.foldX" | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
__author__ = "Mojmir Mutny" | ||||||||||||||||||||||
__all__ = ["FoldXApp"] | ||||||||||||||||||||||
|
||||||||||||||||||||||
import copy | ||||||||||||||||||||||
from tempfile import NamedTemporaryFile | ||||||||||||||||||||||
import numpy as np | ||||||||||||||||||||||
import os | ||||||||||||||||||||||
from os import chdir, getcwd, remove | ||||||||||||||||||||||
from ..localapp import LocalApp, cleanup_tempfile | ||||||||||||||||||||||
from ..application import AppState, requires_state | ||||||||||||||||||||||
from ...structure.io.pdbqt import PDBQTFile | ||||||||||||||||||||||
from ...structure.io.pdb import PDBFile | ||||||||||||||||||||||
from ...structure.io.pdbx import PDBxFile | ||||||||||||||||||||||
from ...structure.residues import get_residue_starts_for, get_residue_masks | ||||||||||||||||||||||
from ...structure.bonds import find_connected | ||||||||||||||||||||||
from ...structure.error import BadStructureError | ||||||||||||||||||||||
Comment on lines
+9
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A lot of these imports are actually unused. Please remove the unused imports, when you finished your work on the PR. |
||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
class FoldXApp(LocalApp): | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I read so far, FoldX has multiple subcommands, and the one used here is called
Suggested change
This is consistent with e.g. the |
||||||||||||||||||||||
""" | ||||||||||||||||||||||
Mutate a protein with *FoldX* | ||||||||||||||||||||||
|
||||||||||||||||||||||
Parameters | ||||||||||||||||||||||
---------- | ||||||||||||||||||||||
receptor : AtomArray, shape=(n,) | ||||||||||||||||||||||
The structure of the proiten molecule. | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
mutation : str, in classical mutation format | ||||||||||||||||||||||
subunit : std, a subunit index in the pdb file | ||||||||||||||||||||||
Comment on lines
+33
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This parameter description style is not consistent with NumpyDoc. |
||||||||||||||||||||||
bin_path : str, optional | ||||||||||||||||||||||
Path to the *FoldX* binary. | ||||||||||||||||||||||
|
||||||||||||||||||||||
Examples | ||||||||||||||||||||||
-------- | ||||||||||||||||||||||
>>> # simple protein | ||||||||||||||||||||||
>>> >>> receptor = atom_array | ||||||||||||||||||||||
>>> app = FoldXApp(receptor, | ||||||||||||||||||||||
... "A34G+E44G", subunit = "A" | ||||||||||||||||||||||
... ) | ||||||||||||||||||||||
Comment on lines
+40
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
""" | ||||||||||||||||||||||
|
||||||||||||||||||||||
def __init__(self, receptor, mutation, subunit = 'B', bin_path="foldx"): | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PEP 8 fix
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
super().__init__(bin_path) | ||||||||||||||||||||||
|
||||||||||||||||||||||
self._receptor = receptor.copy() | ||||||||||||||||||||||
self._mutation = mutation | ||||||||||||||||||||||
self._subunit = subunit | ||||||||||||||||||||||
self._seed = None | ||||||||||||||||||||||
|
||||||||||||||||||||||
self._receptor_file = NamedTemporaryFile( | ||||||||||||||||||||||
"w", suffix=".pdb", delete=False | ||||||||||||||||||||||
) | ||||||||||||||||||||||
self._mutated_receptor_file = NamedTemporaryFile( | ||||||||||||||||||||||
"w", suffix=".pdb", delete=False | ||||||||||||||||||||||
) | ||||||||||||||||||||||
|
||||||||||||||||||||||
self._rotabase_file = NamedTemporaryFile( | ||||||||||||||||||||||
"w", suffix=".txt", delete=False | ||||||||||||||||||||||
) | ||||||||||||||||||||||
|
||||||||||||||||||||||
self._folding_file = NamedTemporaryFile( | ||||||||||||||||||||||
"w", suffix=".txt", delete=False, prefix = "individual_list" | ||||||||||||||||||||||
) | ||||||||||||||||||||||
|
||||||||||||||||||||||
@requires_state(AppState.CREATED) | ||||||||||||||||||||||
def set_seed(self, seed): | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
Fix the seed for the random number generator to get | ||||||||||||||||||||||
reproducible results. | ||||||||||||||||||||||
|
||||||||||||||||||||||
By default, the seed is chosen randomly. | ||||||||||||||||||||||
|
||||||||||||||||||||||
Parameters | ||||||||||||||||||||||
---------- | ||||||||||||||||||||||
seed : int | ||||||||||||||||||||||
The seed for the random number generator. | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
self._seed = seed | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
def setup_folding_file(self, subunit, mutation): | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
Create a temporarily folding file for the mutation | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
Parameters | ||||||||||||||||||||||
---------- | ||||||||||||||||||||||
subnut: str | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
mutation :str | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
entry = [elem[0]+subunit+elem[1:] for elem in mutation.split("+")] | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PEP 8 fix
Suggested change
|
||||||||||||||||||||||
self._folding_file.write(";".join(entry)+";\n") | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PEP 8 fix
Suggested change
|
||||||||||||||||||||||
self._folding_file.flush() | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
def run(self): | ||||||||||||||||||||||
# Use different atom ID ranges for atoms in ligand and receptor | ||||||||||||||||||||||
# for unambiguous assignment, if the receptor contains flexible | ||||||||||||||||||||||
# residues | ||||||||||||||||||||||
receptor_file = PDBFile() | ||||||||||||||||||||||
receptor_file.set_structure(self._receptor) | ||||||||||||||||||||||
receptor_file.write(self._receptor_file) | ||||||||||||||||||||||
|
||||||||||||||||||||||
self._receptor_file.flush() | ||||||||||||||||||||||
|
||||||||||||||||||||||
# set up folding file | ||||||||||||||||||||||
self.setup_folding_file(self._subunit,self._mutation) | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PEP 8 fix
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
# tempfile | ||||||||||||||||||||||
temp = "/".join(self._receptor_file.name.split("/")[0:-1]) | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use |
||||||||||||||||||||||
|
||||||||||||||||||||||
# set up rotabase - copy to tempfile | ||||||||||||||||||||||
rotabase_path = "/".join(os.path.realpath(__file__).split("/")[0:-1])+"/rotabase.txt" | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the |
||||||||||||||||||||||
#os.popen('cp '+rotabase_path+' '+getcwd()+"/rotabase.txt") | ||||||||||||||||||||||
os.popen('cp '+rotabase_path+' '+self._rotabase_file.name) | ||||||||||||||||||||||
Comment on lines
+119
to
+120
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think using |
||||||||||||||||||||||
|
||||||||||||||||||||||
arguments = [ | ||||||||||||||||||||||
"--command", "BuildModel", | ||||||||||||||||||||||
"--pdb", self._receptor_file.name.split("/")[-1], | ||||||||||||||||||||||
"--pdb-dir", temp, | ||||||||||||||||||||||
"--mutant-file", self._folding_file.name, | ||||||||||||||||||||||
"--output-dir", temp, | ||||||||||||||||||||||
"--rotabaseLocation", self._rotabase_file.name, | ||||||||||||||||||||||
#"--output-file", self._mutated_receptor_file.name.split("/")[-1], | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
"--clean-mode", "1", | ||||||||||||||||||||||
"--pdbHydrogens","1" | ||||||||||||||||||||||
] | ||||||||||||||||||||||
self._output_filename = temp+"/"+self._receptor_file.name.split("/")[-1][:-4]+"_1.pdb" | ||||||||||||||||||||||
self.set_arguments(arguments) | ||||||||||||||||||||||
|
||||||||||||||||||||||
super().run() | ||||||||||||||||||||||
|
||||||||||||||||||||||
def clean_up(self): | ||||||||||||||||||||||
super().clean_up() | ||||||||||||||||||||||
cleanup_tempfile(self._receptor_file) | ||||||||||||||||||||||
cleanup_tempfile(self._mutated_receptor_file) | ||||||||||||||||||||||
cleanup_tempfile(self._folding_file) | ||||||||||||||||||||||
cleanup_tempfile(self._rotabase_file) | ||||||||||||||||||||||
|
||||||||||||||||||||||
# remove rotabase file | ||||||||||||||||||||||
#os.remove(getcwd()+"/rotabase.txt") | ||||||||||||||||||||||
|
||||||||||||||||||||||
# remove output_file | ||||||||||||||||||||||
os.remove(self._output_filename) | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
def evaluate(self): | ||||||||||||||||||||||
super().evaluate() | ||||||||||||||||||||||
out_file = PDBFile.read(self._output_filename) | ||||||||||||||||||||||
models = out_file.get_structure(include_bonds = True, model=1) | ||||||||||||||||||||||
self.new_mutant = models | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this variable can be considered private.
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
@requires_state(AppState.JOINED) | ||||||||||||||||||||||
def get_mutant(self): | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
Get the mutant protein structure | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
Returns | ||||||||||||||||||||||
------- | ||||||||||||||||||||||
ligand : AtomArrayStack | ||||||||||||||||||||||
The mutated protein | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
""" | ||||||||||||||||||||||
return self.new_mutant | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
@staticmethod | ||||||||||||||||||||||
def mutate(receptor, mutation, bin_path="vina"): | ||||||||||||||||||||||
""" | ||||||||||||||||||||||
Mutate the protein with *FoldX BuildModel*. | ||||||||||||||||||||||
|
||||||||||||||||||||||
This is a convenience function, that wraps the :class:`FoldX` | ||||||||||||||||||||||
execution. | ||||||||||||||||||||||
|
||||||||||||||||||||||
Parameters | ||||||||||||||||||||||
---------- | ||||||||||||||||||||||
|
||||||||||||||||||||||
Returns | ||||||||||||||||||||||
------- | ||||||||||||||||||||||
|
||||||||||||||||||||||
""" | ||||||||||||||||||||||
app = FoldXApp( receptor, mutation, bin_path) | ||||||||||||||||||||||
app.start() | ||||||||||||||||||||||
app.join() | ||||||||||||||||||||||
return app.get_mutant() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.