Coverage for biobb_model/model/mutate.py: 69%
55 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 11:32 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 11:32 +0000
1#!/usr/bin/env python3
3"""Module containing the Mutate class and the command line interface."""
5import argparse
6from typing import Optional
8from biobb_common.configuration import settings
9from biobb_common.generic.biobb_object import BiobbObject
10from biobb_common.tools import file_utils as fu
11from biobb_common.tools.file_utils import launchlogger
13from biobb_model.model.common import modeller_installed
16class Mutate(BiobbObject):
17 """
18 | biobb_model Mutate
19 | Class to mutate one amino acid by another in a 3d structure.
20 | Mutate side chain with minimal atom replacement. if the use_modeller property is added the `Modeller suite <https://salilab.org/modeller/>`_ will be used to optimize the side chains.
22 Args:
23 input_pdb_path (str): Input PDB file path. File type: input. `Sample file <https://github.com/bioexcel/biobb_model/raw/master/biobb_model/test/data/model/2ki5.pdb>`_. Accepted formats: pdb (edam:format_1476).
24 output_pdb_path (str): Output PDB file path. File type: output. `Sample file <https://github.com/bioexcel/biobb_model/raw/master/biobb_model/test/reference/model/output_mutated_pdb_path.pdb>`_. Accepted formats: pdb (edam:format_1476).
25 properties (dict - Python dictionary object containing the tool parameters, not input/output files):
26 * **mutation_list** (*str*) - (None) Mutation list in the format "Chain:WT_AA_ThreeLeterCode Resnum MUT_AA_ThreeLeterCode" (no spaces between the elements) separated by commas. If no chain is provided as chain code all the chains in the pdb file will be mutated. ie: "A:ALA15CYS"
27 * **use_modeller** (*bool*) - (False) Use `Modeller suite <https://salilab.org/modeller/>`_ to optimize the side chains.
28 * **modeller_key** (*str*) - (None) Modeller license key.
29 * **binary_path** (*str*) - ("check_structure") Path to the check_structure executable binary.
30 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
31 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
32 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory.
34 Examples:
35 This is a use example of how to use the building block from Python::
37 from biobb_model.model.mutate import mutate
38 prop = { 'mutation_list': 'A:Val2Ala',
39 'use_modeller': True }
40 mutate(input_pdb_path='/path/to/myStructure.pdb',
41 output_pdb_path='/path/to/newStructure.pdb',
42 properties=prop)
44 Info:
45 * wrapped_software:
46 * name: In house
47 * license: Apache-2.0
48 * ontology:
49 * name: EDAM
50 * schema: http://edamontology.org/EDAM.owl
51 """
53 def __init__(
54 self,
55 input_pdb_path: str,
56 output_pdb_path: str,
57 properties: Optional[dict] = None,
58 **kwargs,
59 ) -> None:
60 properties = properties or {}
62 # Call parent class constructor
63 super().__init__(properties)
64 self.locals_var_dict = locals().copy()
66 # Input/Output files
67 self.io_dict = {
68 "in": {"input_pdb_path": input_pdb_path},
69 "out": {"output_pdb_path": output_pdb_path},
70 }
72 # Properties specific for BB
73 self.binary_path = properties.get("binary_path", "check_structure")
74 self.mutation_list = properties.get("mutation_list", "").replace(" ", "")
75 self.use_modeller = properties.get("use_modeller", False)
76 self.modeller_key = properties.get("modeller_key")
78 # Check the properties
79 self.check_properties(properties)
80 self.check_arguments()
82 @launchlogger
83 def launch(self) -> int:
84 """Execute the :class:`Mutate <model.mutate.Mutate>` object."""
86 # Setup Biobb
87 if self.check_restart():
88 return 0
89 self.stage_files()
91 # Create command line
92 self.cmd = [
93 self.binary_path,
94 "-i",
95 self.stage_io_dict["in"]["input_pdb_path"],
96 "-o",
97 self.stage_io_dict["out"]["output_pdb_path"],
98 "--force_save",
99 "--non_interactive",
100 "mutateside",
101 ]
103 if self.mutation_list:
104 self.cmd.append("--mut")
105 self.cmd.append(self.mutation_list)
107 if self.modeller_key:
108 self.cmd.insert(1, self.modeller_key)
109 self.cmd.insert(1, "--modeller_key")
111 if self.use_modeller:
112 if modeller_installed(self.out_log, self.global_log):
113 self.cmd.append("--rebuild")
114 else:
115 fu.log(
116 "Modeller is not installed --rebuild option can not be used proceeding without using it",
117 self.out_log,
118 self.global_log,
119 )
121 # Run Biobb block
122 self.run_biobb()
124 # Copy files to host
125 self.copy_to_host()
127 # Remove temporal files
128 # self.tmp_files.append(self.stage_io_dict.get("unique_dir", ""))
129 # self.tmp_files.extend([self.stage_io_dict.get("unique_dir", "")])
130 self.remove_tmp_files()
132 self.check_arguments(output_files_created=True, raise_exception=False)
133 return self.return_code
136def mutate(
137 input_pdb_path: str,
138 output_pdb_path: str,
139 properties: Optional[dict] = None,
140 **kwargs,
141) -> int:
142 """Create :class:`Mutate <model.mutate.Mutate>` class and
143 execute the :meth:`launch() <model.mutate.Mutate.launch>` method."""
144 return Mutate(
145 input_pdb_path=input_pdb_path,
146 output_pdb_path=output_pdb_path,
147 properties=properties,
148 **kwargs,
149 ).launch()
151 mutate.__doc__ = Mutate.__doc__
154def main():
155 parser = argparse.ArgumentParser(
156 description="Model the missing atoms in aminoacid side chains of a PDB.",
157 formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999),
158 )
159 parser.add_argument(
160 "-c",
161 "--config",
162 required=False,
163 help="This file can be a YAML file, JSON file or JSON string",
164 )
166 # Specific args of each building block
167 required_args = parser.add_argument_group("required arguments")
168 required_args.add_argument(
169 "-i", "--input_pdb_path", required=True, help="Input PDB file name"
170 )
171 required_args.add_argument(
172 "-o", "--output_pdb_path", required=True, help="Output PDB file name"
173 )
175 args = parser.parse_args()
176 config = args.config if args.config else None
177 properties = settings.ConfReader(config=config).get_prop_dic()
179 # Specific call of each building block
180 mutate(
181 input_pdb_path=args.input_pdb_path,
182 output_pdb_path=args.output_pdb_path,
183 properties=properties,
184 )
187if __name__ == "__main__":
188 main()