Coverage for biobb_godmd/godmd/godmd_run.py: 19%
91 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-25 07:50 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-25 07:50 +0000
1#!/usr/bin/env python3
3"""Module containing the GOdMDRun class and the command line interface."""
5import argparse
6import shutil
7from pathlib import Path, PurePath
8from typing import Optional
10from biobb_common.configuration import settings
11from biobb_common.generic.biobb_object import BiobbObject
12from biobb_common.tools.file_utils import launchlogger
14from biobb_godmd.godmd.common import check_input_path, check_output_path
17class GOdMDRun(BiobbObject):
18 """
19 | biobb_godmd GOdMDRun
20 | Wrapper of the `GOdMD tool <http://mmb.irbbarcelona.org/GOdMD/>`_ module.
21 | Computes conformational transition trajectories for proteins using GOdMD tool.
23 Args:
24 input_pdb_orig_path (str): Input PDB file to be used as origin in the conformational transition. File type: input. `Sample file <https://github.com/bioexcel/biobb_godmd/raw/master/biobb_godmd/test/data/godmd/1ake_A.pdb>`_. Accepted formats: pdb (edam:format_1476).
25 input_pdb_target_path (str): Input PDB file to be used as target in the conformational transition. File type: input. `Sample file <https://github.com/bioexcel/biobb_godmd/raw/master/biobb_godmd/test/data/godmd/4ake_A.pdb>`_. Accepted formats: pdb (edam:format_1476).
26 input_aln_orig_path (str): Input GOdMD alignment file corresponding to the origin structure of the conformational transition. File type: input. `Sample file <https://github.com/bioexcel/biobb_godmd/raw/master/biobb_godmd/test/data/godmd/1ake_A.aln>`_. Accepted formats: aln (edam:format_2330), txt (edam:format_2330).
27 input_aln_target_path (str): Input GOdMD alignment file corresponding to the target structure of the conformational transition. File type: input. `Sample file <https://github.com/bioexcel/biobb_godmd/raw/master/biobb_godmd/test/data/godmd/4ake_A.aln>`_. Accepted formats: aln (edam:format_2330), txt (edam:format_2330).
28 input_config_path (str) (Optional): Input GOdMD configuration file. File type: input. `Sample file <https://github.com/bioexcel/biobb_godmd/raw/master/biobb_godmd/test/data/godmd/params.in>`_. Accepted formats: in (edam:format_2330), txt (edam:format_2330).
29 output_log_path (str): Output log file. File type: output. `Sample file <https://github.com/bioexcel/biobb_godmd/raw/master/biobb_godmd/test/reference/godmd/godmd.log>`_. Accepted formats: log (edam:format_2330), out (edam:format_2330), txt (edam:format_2330), o (edam:format_2330).
30 output_ene_path (str): Output energy file. File type: output. `Sample file <https://github.com/bioexcel/biobb_godmd/raw/master/biobb_godmd/test/reference/godmd/godmd_ene.out>`_. Accepted formats: log (edam:format_2330), out (edam:format_2330), txt (edam:format_2330), o (edam:format_2330).
31 output_trj_path (str): Output trajectory file. File type: output. `Sample file <https://github.com/bioexcel/biobb_godmd/raw/master/biobb_godmd/test/reference/godmd/godmd_trj.mdcrd>`_. Accepted formats: trj (edam:format_3878), crd (edam:format_3878), mdcrd (edam:format_3878), x (edam:format_3878).
32 output_pdb_path (str): Output structure file. File type: output. `Sample file <https://github.com/bioexcel/biobb_godmd/raw/master/biobb_godmd/test/reference/godmd/godmd_pdb.pdb>`_. Accepted formats: pdb (edam:format_1476).
33 properties (dict - Python dictionary object containing the tool parameters, not input/output files):
34 * **godmdin** (*dict*) - ({}) GOdMD options specification.
35 * **binary_path** (*str*) - ("discrete") Binary path.
36 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
37 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
38 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory.
40 Examples:
41 This is a use example of how to use the building block from Python::
43 from biobb_godmd.godmd.godmd_run import godmd_run
44 prop = {
45 'remove_tmp': True
46 }
47 godmd_run( input_pdb_orig_path='/path/to/pdb_orig.pdb',
48 input_pdb_target_path='/path/to/pdb_target.pdb',
49 input_aln_orig_path='/path/to/aln_orig.aln',
50 input_aln_target_path='/path/to/aln_target.aln',
51 output_log_path='/path/to/godmd_log.log',
52 output_ene_path='/path/to/godmd_ene.txt',
53 output_trj_path='/path/to/godmd_trj.mdcrd',
54 output_pdb_path='/path/to/godmd_pdb.pdb',
55 properties=prop)
57 Info:
58 * wrapped_software:
59 * name: GOdMD
60 * version: >=1.0
61 * license: Apache-2.0
62 * ontology:
63 * name: EDAM
64 * schema: http://edamontology.org/EDAM.owl
66 """
68 def __init__(
69 self,
70 input_pdb_orig_path: str,
71 input_pdb_target_path: str,
72 input_aln_orig_path: str,
73 input_aln_target_path: str,
74 input_config_path: Optional[str],
75 output_log_path: str,
76 output_ene_path: str,
77 output_trj_path: str,
78 output_pdb_path: str,
79 properties: Optional[dict] = None,
80 **kwargs,
81 ) -> None:
82 properties = properties or {}
84 # Call parent class constructor
85 super().__init__(properties)
86 self.locals_var_dict = locals().copy()
88 # Input/Output files
89 self.io_dict = {
90 "in": {
91 "input_pdb_orig_path": input_pdb_orig_path,
92 "input_pdb_target_path": input_pdb_target_path,
93 "input_aln_orig_path": input_aln_orig_path,
94 "input_aln_target_path": input_aln_target_path,
95 "input_config_path": input_config_path,
96 },
97 "out": {
98 "output_log_path": output_log_path,
99 "output_ene_path": output_ene_path,
100 "output_trj_path": output_trj_path,
101 "output_pdb_path": output_pdb_path,
102 },
103 }
105 # Properties specific for BB
106 self.properties = properties
107 self.godmdin = {k: str(v) for k, v in properties.get("godmdin", dict()).items()}
108 self.binary_path = properties.get("binary_path", "discrete")
110 # Check the properties
111 self.check_properties(properties)
112 # self.check_arguments()
114 def check_data_params(self, out_log, out_err):
115 """Checks input/output paths correctness"""
117 # Check input(s)
118 self.io_dict["in"]["input_pdb_orig_path"] = check_input_path(
119 self.io_dict["in"]["input_pdb_orig_path"],
120 "input_pdb_orig_path",
121 False,
122 out_log,
123 self.__class__.__name__,
124 )
125 self.io_dict["in"]["input_pdb_target_path"] = check_input_path(
126 self.io_dict["in"]["input_pdb_target_path"],
127 "input_pdb_target_path",
128 False,
129 out_log,
130 self.__class__.__name__,
131 )
132 self.io_dict["in"]["input_aln_orig_path"] = check_input_path(
133 self.io_dict["in"]["input_aln_orig_path"],
134 "input_aln_orig_path",
135 False,
136 out_log,
137 self.__class__.__name__,
138 )
139 self.io_dict["in"]["input_aln_target_path"] = check_input_path(
140 self.io_dict["in"]["input_aln_target_path"],
141 "input_aln_target_path",
142 False,
143 out_log,
144 self.__class__.__name__,
145 )
146 self.io_dict["in"]["input_config_path"] = check_input_path(
147 self.io_dict["in"]["input_config_path"],
148 "input_config_path",
149 True,
150 out_log,
151 self.__class__.__name__,
152 )
154 # Check output(s)
155 self.io_dict["out"]["output_log_path"] = check_output_path(
156 self.io_dict["out"]["output_log_path"],
157 "output_log_path",
158 False,
159 out_log,
160 self.__class__.__name__,
161 )
162 self.io_dict["out"]["output_ene_path"] = check_output_path(
163 self.io_dict["out"]["output_ene_path"],
164 "output_ene_path",
165 False,
166 out_log,
167 self.__class__.__name__,
168 )
169 self.io_dict["out"]["output_trj_path"] = check_output_path(
170 self.io_dict["out"]["output_trj_path"],
171 "output_trj_path",
172 False,
173 out_log,
174 self.__class__.__name__,
175 )
176 self.io_dict["out"]["output_pdb_path"] = check_output_path(
177 self.io_dict["out"]["output_pdb_path"],
178 "output_pdb_path",
179 False,
180 out_log,
181 self.__class__.__name__,
182 )
184 def create_godmdin(self, path: Optional[str] = None) -> str:
185 """Creates a GOdMD configuration file (godmdin) using the properties file settings"""
186 godmdin_list = []
188 self.output_godmdin_path = path
190 if self.io_dict["in"]["input_config_path"]:
191 # GOdMD input parameters read from an input godmdin file
192 with open(self.io_dict["in"]["input_config_path"]) as input_params:
193 for line in input_params:
194 if "=" in line:
195 godmdin_list.append(line.upper())
196 else:
197 # Pre-configured simulation type parameters
198 godmdin_list.append(" TSNAP = 500 ! BioBB GOdMD default params \n")
199 godmdin_list.append(" TEMP = 300 ! BioBB GOdMD default params \n")
200 godmdin_list.append(" SEED = 2525 ! BioBB GOdMD default params \n")
201 godmdin_list.append(" ENER_EVO_SIZE = 20 ! BioBB GOdMD default params \n")
202 godmdin_list.append(" NBLOC = 10000 ! BioBB GOdMD default params \n")
203 godmdin_list.append(
204 " ERRORACCEPTABLE = 1.5 ! BioBB GOdMD default params \n"
205 )
207 # Adding the rest of parameters in the config file to the mdin file
208 # if the parameter has already been added replace the value
209 parameter_keys = [parameter.split("=")[0].strip() for parameter in godmdin_list]
210 for k, v in self.godmdin.items():
211 config_parameter_key = str(k).strip().upper()
212 if config_parameter_key in parameter_keys:
213 godmdin_list[parameter_keys.index(config_parameter_key)] = (
214 "\t" + config_parameter_key + " = " + str(v) + " ! BioBB property \n"
215 )
216 else:
217 godmdin_list.append(
218 "\t" + config_parameter_key + " = " + str(v) + " ! BioBB property \n"
219 )
221 # Writing MD configuration file (mdin)
222 with open(str(self.output_godmdin_path), "w") as godmdin:
223 # GOdMDIN parameters added by the biobb_godmd module
224 godmdin.write(
225 "!This godmdin file has been created by the biobb_godmd module from the BioBB library \n\n"
226 )
228 godmdin.write("&INPUT\n")
230 # MD config parameters
231 for line in godmdin_list:
232 godmdin.write(line)
234 godmdin.write("&END\n")
236 return str(self.output_godmdin_path)
238 @launchlogger
239 def launch(self):
240 """Launches the execution of the GOdMDRun module."""
242 # check input/output paths and parameters
243 self.check_data_params(self.out_log, self.err_log)
245 # Setup Biobb
246 if self.check_restart():
247 return 0
248 self.stage_files()
250 # Creating GOdMD input file
251 self.output_godmdin_path = self.create_godmdin(
252 path=str(Path(self.stage_io_dict["unique_dir"]).joinpath("godmd.in"))
253 )
255 # Command line
256 # discrete -i $fileName.in -pdbin $pdbch1 -pdbtarg $pdbch2 -ener $fileName.ene -trj $fileName.crd -p1 $alignFile1 -p2 $alignFile2 -o $fileName.log >& $fileName.out
257 self.cmd = [
258 "cd",
259 self.stage_io_dict["unique_dir"],
260 ";",
261 self.binary_path,
262 "-i",
263 "godmd.in",
264 "-pdbin",
265 PurePath(self.stage_io_dict["in"]["input_pdb_orig_path"]).name,
266 "-pdbtarg",
267 PurePath(self.stage_io_dict["in"]["input_pdb_target_path"]).name,
268 "-p1",
269 PurePath(self.stage_io_dict["in"]["input_aln_orig_path"]).name,
270 "-p2",
271 PurePath(self.stage_io_dict["in"]["input_aln_target_path"]).name,
272 "-o",
273 PurePath(self.stage_io_dict["out"]["output_log_path"]).name,
274 "-ener",
275 PurePath(self.stage_io_dict["out"]["output_ene_path"]).name,
276 "-trj",
277 PurePath(self.stage_io_dict["out"]["output_trj_path"]).name,
278 ]
280 # Run Biobb block
281 self.run_biobb()
283 # Copy outputs from temporary folder to output path
284 shutil.copy2(
285 str(Path(self.stage_io_dict["unique_dir"]).joinpath("reference.pdb")),
286 PurePath(self.io_dict["out"]["output_pdb_path"]),
287 )
289 # Copy files to host
290 self.copy_to_host()
292 # remove temporary folder(s)
293 # self.tmp_files.extend([
294 # self.stage_io_dict.get("unique_dir", ""),
295 # ])
296 self.remove_tmp_files()
298 self.check_arguments(output_files_created=True, raise_exception=False)
300 return self.return_code
303def godmd_run(
304 input_pdb_orig_path: str,
305 input_pdb_target_path: str,
306 input_aln_orig_path: str,
307 input_aln_target_path: str,
308 output_log_path: str,
309 output_ene_path: str,
310 output_trj_path: str,
311 output_pdb_path: str,
312 input_config_path: Optional[str] = None,
313 properties: Optional[dict] = None,
314 **kwargs,
315) -> int:
316 """Create :class:`GOdMDRun <godmd.godmd_run.GOdMDRun>`godmd.godmd_run.GOdMDRun class and
317 execute :meth:`launch() <godmd.godmd_run.GOdMDRun.launch>` method"""
319 return GOdMDRun(
320 input_pdb_orig_path=input_pdb_orig_path,
321 input_pdb_target_path=input_pdb_target_path,
322 input_aln_orig_path=input_aln_orig_path,
323 input_aln_target_path=input_aln_target_path,
324 input_config_path=input_config_path,
325 output_log_path=output_log_path,
326 output_ene_path=output_ene_path,
327 output_trj_path=output_trj_path,
328 output_pdb_path=output_pdb_path,
329 properties=properties,
330 ).launch()
332 godmd_run.__doc__ = GOdMDRun.__doc__
335def main():
336 parser = argparse.ArgumentParser(
337 description="Computing conformational transition trajectories for proteins using GOdMD tool.",
338 formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999),
339 )
340 parser.add_argument("--config", required=False, help="Configuration file")
342 # Specific args
343 required_args = parser.add_argument_group("required arguments")
344 required_args.add_argument(
345 "--input_pdb_orig_path",
346 required=True,
347 help="Input PDB file to be used as origin in the conformational transition. Accepted formats: pdb.",
348 )
349 required_args.add_argument(
350 "--input_pdb_target_path",
351 required=True,
352 help="Input PDB file to be used as target in the conformational transition. Accepted formats: pdb.",
353 )
354 required_args.add_argument(
355 "--input_aln_orig_path",
356 required=True,
357 help="Input GOdMD alignment file corresponding to the origin structure of the conformational transition. Accepted formats: aln, txt.",
358 )
359 required_args.add_argument(
360 "--input_aln_target_path",
361 required=True,
362 help="Input GOdMD alignment file corresponding to the target structure of the conformational transition. Accepted formats: aln, txt.",
363 )
364 required_args.add_argument(
365 "--input_config_path",
366 required=False,
367 help="Input configuration file (GOdMD run options). Accepted formats: in, txt.",
368 )
369 required_args.add_argument(
370 "--output_log_path",
371 required=True,
372 help="Output log file. Accepted formats: log, out, txt.",
373 )
374 required_args.add_argument(
375 "--output_ene_path",
376 required=True,
377 help="Output energy file. Accepted formats: log, out, txt.",
378 )
379 required_args.add_argument(
380 "--output_trj_path",
381 required=True,
382 help="Output trajectory file. Accepted formats: mdcrd.",
383 )
384 required_args.add_argument(
385 "--output_pdb_path",
386 required=True,
387 help="Output structure file. Accepted formats: pdb.",
388 )
390 args = parser.parse_args()
391 # config = args.config if args.config else None
392 args.config = args.config or "{}"
393 # properties = settings.ConfReader(config=config).get_prop_dic()
394 properties = settings.ConfReader(config=args.config).get_prop_dic()
396 # Specific call
397 godmd_run(
398 input_pdb_orig_path=args.input_pdb_orig_path,
399 input_pdb_target_path=args.input_pdb_target_path,
400 input_aln_orig_path=args.input_aln_orig_path,
401 input_aln_target_path=args.input_aln_target_path,
402 input_config_path=args.input_config_path,
403 output_log_path=args.output_log_path,
404 output_ene_path=args.output_ene_path,
405 output_trj_path=args.output_trj_path,
406 output_pdb_path=args.output_pdb_path,
407 properties=properties,
408 )
411if __name__ == "__main__":
412 main()